diff --git a/software/FusionX/bin/k64fcpu b/software/FusionX/bin/k64fcpu index 7a0ebca95..45e8eb4a3 100755 Binary files a/software/FusionX/bin/k64fcpu and b/software/FusionX/bin/k64fcpu differ diff --git a/software/FusionX/bin/sharpbiter b/software/FusionX/bin/sharpbiter index c10c6ba1f..4b327409b 100755 Binary files a/software/FusionX/bin/sharpbiter and b/software/FusionX/bin/sharpbiter differ diff --git a/software/FusionX/bin/z80ctrl b/software/FusionX/bin/z80ctrl index fbf5ee300..8411ef107 100755 Binary files a/software/FusionX/bin/z80ctrl and b/software/FusionX/bin/z80ctrl differ diff --git a/software/FusionX/modules/ttymzdrv.ko b/software/FusionX/modules/ttymzdrv.ko index e164d17ed..5d601b906 100644 Binary files a/software/FusionX/modules/ttymzdrv.ko and b/software/FusionX/modules/ttymzdrv.ko differ diff --git a/software/FusionX/modules/z80drv.ko b/software/FusionX/modules/z80drv.ko index 4fa2aa404..92db948b6 100644 Binary files a/software/FusionX/modules/z80drv.ko and b/software/FusionX/modules/z80drv.ko differ diff --git a/software/FusionX/src/ttymz/Makefile b/software/FusionX/src/ttymz/Makefile index a94f9a45e..507105be0 100644 --- a/software/FusionX/src/ttymz/Makefile +++ b/software/FusionX/src/ttymz/Makefile @@ -1,5 +1,6 @@ # Select the target host. #MODEL := MZ2000 +#MODEL := MZ1500 #MODEL := MZ700 #MODEL := MZ80A #MODEL := PCW8XXX @@ -26,6 +27,7 @@ all: MZ80A: MODEL_MZ80A MZ700: MODEL_MZ700 +MZ1500: MODEL_MZ1500 MZ2000: MODEL_MZ2000 PCW8XXX: MODEL_PCW8XXX PCW9XXX: MODEL_PCW9XXX @@ -34,6 +36,8 @@ MODEL_MZ80A: $(MAKE) MODEL=MZ80A BUILD_MZ80A MODEL_MZ700: $(MAKE) MODEL=MZ700 BUILD_MZ700 +MODEL_MZ1500: + $(MAKE) MODEL=MZ1500 BUILD_MZ1500 MODEL_MZ2000: $(MAKE) MODEL=MZ2000 BUILD_MZ2000 MODEL_PCW8XXX: @@ -43,6 +47,7 @@ MODEL_PCW9XXX: BUILD_MZ80A: kmod BUILD_MZ700: kmod +BUILD_MZ1500: kmod BUILD_MZ2000: kmod BUILD_PCW8XXX: kmod BUILD_PCW9XXX: kmod diff --git a/software/FusionX/src/ttymz/sharpmz.c b/software/FusionX/src/ttymz/sharpmz.c index 6ca787940..f81d46756 100644 --- a/software/FusionX/src/ttymz/sharpmz.c +++ b/software/FusionX/src/ttymz/sharpmz.c @@ -13,6 +13,7 @@ // // History: v1.0 Feb 2023 - Initial write of the Sharp MZ series hardware interface software. // v1.01 Mar 2023 - Bug fixes and additional ESC sequence processing. +// v1.02 May 2023 - Updates to accommodate MZ-1500 host. // // Notes: See Makefile to enable/disable conditional components // @@ -213,478 +214,141 @@ static t_dispCodeMap dispCodeMap[] = { { 0xA5 }, // ~ { 0xC0 } // DEL }; +// TODO: Change this mapping to reflect MZ-1500 ATB bit, update VRAM/ATBRAM macro. +#elif (TARGET_HOST_MZ1500 == 1) +static t_dispCodeMap dispCodeMap[] = { + { 0xCC }, // NUL '\0' (null character) + { 0xE0 }, // SOH (start of heading) + { 0xF2 }, // STX (start of text) + { 0xF3 }, // ETX (end of text) + { 0xCE }, // EOT (end of transmission) + { 0xCF }, // ENQ (enquiry) + { 0xF6 }, // ACK (acknowledge) + { 0xF7 }, // BEL '\a' (bell) + { 0xF8 }, // BS '\b' (backspace) + { 0xF9 }, // HT '\t' (horizontal tab) + { 0xFA }, // LF '\n' (new line) + { 0xFB }, // VT '\v' (vertical tab) + { 0xFC }, // FF '\f' (form feed) + { 0xFD }, // CR '\r' (carriage ret) + { 0xFE }, // SO (shift out) + { 0xFF }, // SI (shift in) + { 0xE1 }, // DLE (data link escape) + { 0xC1 }, // DC1 (device control 1) + { 0xC2 }, // DC2 (device control 2) + { 0xC3 }, // DC3 (device control 3) + { 0xC4 }, // DC4 (device control 4) + { 0xC5 }, // NAK (negative ack.) + { 0xC6 }, // SYN (synchronous idle) + { 0xE2 }, // ETB (end of trans. blk) + { 0xE3 }, // CAN (cancel) + { 0xE4 }, // EM (end of medium) + { 0xE5 }, // SUB (substitute) + { 0xE6 }, // ESC (escape) + { 0xEB }, // FS (file separator) + { 0xEE }, // GS (group separator) + { 0xEF }, // RS (record separator) + { 0xF4 }, // US (unit separator) + { 0x00 }, // SPACE + { 0x61 }, // ! + { 0x62 }, // " + { 0x63 }, // # + { 0x64 }, // $ + { 0x65 }, // % + { 0x66 }, // & + { 0x67 }, // ' + { 0x68 }, // ( + { 0x69 }, // ) + { 0x6B }, // * + { 0x6A }, // + + { 0x2F }, // , + { 0x2A }, // - + { 0x2E }, // . + { 0x2D }, // / + { 0x20 }, // 0 + { 0x21 }, // 1 + { 0x22 }, // 2 + { 0x23 }, // 3 + { 0x24 }, // 4 + { 0x25 }, // 5 + { 0x26 }, // 6 + { 0x27 }, // 7 + { 0x28 }, // 8 + { 0x29 }, // 9 + { 0x4F }, // : + { 0x2C }, // ; + { 0x51 }, // < + { 0x2B }, // = + { 0x57 }, // > + { 0x49 }, // ? + { 0x55 }, // @ + { 0x01 }, // A + { 0x02 }, // B + { 0x03 }, // C + { 0x04 }, // D + { 0x05 }, // E + { 0x06 }, // F + { 0x07 }, // G + { 0x08 }, // H + { 0x09 }, // I + { 0x0A }, // J + { 0x0B }, // K + { 0x0C }, // L + { 0x0D }, // M + { 0x0E }, // N + { 0x0F }, // O + { 0x10 }, // P + { 0x11 }, // Q + { 0x12 }, // R + { 0x13 }, // S + { 0x14 }, // T + { 0x15 }, // U + { 0x16 }, // V + { 0x17 }, // W + { 0x18 }, // X + { 0x19 }, // Y + { 0x1A }, // Z + { 0x52 }, // [ + { 0x59 }, // \ '\\' + { 0x54 }, // ] + { 0xBE }, // ^ + { 0x3C }, // _ + { 0xC7 }, // ` + { 0x81 }, // a + { 0x82 }, // b + { 0x83 }, // c + { 0x84 }, // d + { 0x85 }, // e + { 0x86 }, // f + { 0x87 }, // g + { 0x88 }, // h + { 0x89 }, // i + { 0x8A }, // j + { 0x8B }, // k + { 0x8C }, // l + { 0x8D }, // m + { 0x8E }, // n + { 0x8F }, // o + { 0x90 }, // p + { 0x91 }, // q + { 0x92 }, // r + { 0x93 }, // s + { 0x94 }, // t + { 0x95 }, // u + { 0x96 }, // v + { 0x97 }, // w + { 0x98 }, // x + { 0x99 }, // y + { 0x9A }, // z + { 0xBC }, // { + { 0x80 }, // | + { 0x40 }, // } + { 0xA5 }, // ~ + { 0xC0 } // DEL +}; #endif -#if (TARGET_HOST_MZ700 == 1) -static t_scanCodeMap scanCodeMap[] = { - // NO SHIFT - {{ - // S0 00 - 07 - ESC , // SPARE - Allocate as Escape - GRAPHKEY , // GRAPH - '_' , // Pound/Down Arrow - ALPHAKEY , // ALPHA - NOKEY , // NO - ';' , // + - ':' , // * - CR , // CR - // S1 08 - 0F - 'y' , // y - 'z' , // z - '@' , // ` - '[' , // { - ']' , // } - NOKEY , // NULL - NOKEY , // NULL - NOKEY , // NULL - // S2 10 - 17 - 'q' , // q - 'r' , // r - 's' , // s - 't' , // t - 'u' , // u - 'v' , // v - 'w' , // w - 'x' , // x - // S3 18 - 1F - 'i' , // i - 'j' , // j - 'k' , // k - 'l' , // l - 'm' , // m - 'n' , // n - 'o' , // o - 'p' , // p - // S4 20 - 27 - 'a' , // a - 'b' , // b - 'c' , // c - 'd' , // d - 'e' , // e - 'f' , // f - 'g' , // g - 'h' , // h - // S5 28 - 2F - '1' , // 1 - '2' , // 2 - '3' , // 3 - '4' , // 4 - '5' , // 5 - '6' , // 6 - '7' , // 7 - '8' , // 8 - // S6 30 - 37 - '\\' , // Backslash - CURSUP , // - '-' , // - - ' ' , // SPACE - '0' , // 0 - '9' , // 9 - ',' , // , - '.' , // . - // S7 38 - 3F - INSERT , // INST. - DELETE , // DEL. - CURSUP , // CURSOR UP - CURSDOWN , // CURSOR DOWN - CURSRIGHT, // CURSOR RIGHT - CURSLEFT , // CURSOR LEFT - '?' , // Question Mark - '/' , // Forward Slash - // S8 40 - 47 - modifier keys. - BACKS , // BREAK - Backspace without modifiers, like standard ascii keyboards. - NOKEY , // CTRL - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , // SHIFT - // S9 48 - 4F - Function keys. - FUNC1 , // Function key F1 - FUNC2 , // Function key F2 - FUNC3 , // Function key F3 - FUNC4 , // Function key F4 - FUNC5 , // Function key F5 - NOKEY , - NOKEY , - NOKEY - }}, - // CAPS LOCK - {{ - // S0 00 - 07 - ESC , // SPARE - Allocate as Escape - GRAPHKEY , // GRAPH - 0x58 , // - ALPHAKEY , // ALPHA - NOKEY , // NO - ':' , // ; - ';' , // : - CR , // CR - // S1 08 - 0F - 'Y' , // Y - 'Z' , // Z - '@' , // @ - '[' , // [ - ']' , // ] - NOKEY , // NULL - NOKEY , // NULL - NOKEY , // NULL - // S2 10 - 17 - 'Q' , // Q - 'R' , // R - 'S' , // S - 'T' , // T - 'U' , // U - 'V' , // V - 'W' , // W - 'X' , // X - // S3 18 - 1F - 'I' , // I - 'J' , // J - 'K' , // K - 'L' , // L - 'M' , // M - 'N' , // N - 'O' , // O - 'P' , // P - // S4 20 - 27 - 'A' , // A - 'B' , // B - 'C' , // C - 'D' , // D - 'E' , // E - 'F' , // F - 'G' , // G - 'H' , // H - // S5 28 - 2F - '1' , // 1 - '2' , // 2 - '3' , // 3 - '4' , // 4 - '5' , // 5 - '6' , // 6 - '7' , // 7 - '8' , // 8 - // S6 30 - 37 - '\\' , // Backslash - CURSUP , // - '-' , // - - ' ' , // SPACE - '0' , // 0 - '9' , // 9 - ',' , // , - '.' , // . - // S7 38 - 3F - INSERT , // INST. - DELETE , // DEL. - CURSUP , // CURSOR UP - CURSDOWN , // CURSOR DOWN - CURSRIGHT, // CURSOR RIGHT - CURSLEFT , // CURSOR LEFT - '?' , // ? - '/' , // / - // S8 40 - 47 - modifier keys. - BACKS , // BREAK - Backspace without modifiers, like standard ascii keyboards. - NOKEY , // CTRL - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , // SHIFT - // S9 48 - 4F - Function keys. - FUNC1 , // Function key F1 - FUNC2 , // Function key F2 - FUNC3 , // Function key F3 - FUNC4 , // Function key F4 - FUNC5 , // Function key F5 - NOKEY , - NOKEY , - NOKEY - }}, - // SHIFT LOCK. - {{ - // S0 00 - 07 - ESC , // SPARE - Allocate as Escape - GRAPHKEY , // GRAPH - 0x58 , // - ALPHAKEY , // ALPHA - NOKEY , // NO - '+' , // ; - '*' , // : - CR , // CR - // S1 08 - 0F - 'Y' , // Y - 'Z' , // Z - '`' , // @ - '{' , // [ - '}' , // ] - NOKEY , // NULL - NOKEY , // NULL - NOKEY , // NULL - // S2 10 - 17 - 'Q' , // Q - 'R' , // R - 'S' , // S - 'T' , // T - 'U' , // U - 'V' , // V - 'W' , // W - 'X' , // X - // S3 18 - 1F - 'I' , // I - 'J' , // J - 'K' , // K - 'L' , // L - 'M' , // M - 'N' , // N - 'O' , // O - 'P' , // P - // S4 20 - 27 - 'A' , // A - 'B' , // B - 'C' , // C - 'D' , // D - 'E' , // E - 'F' , // F - 'G' , // G - 'H' , // H - // S5 28 - 2F - '!' , // ! - '"' , // " - '#' , // # - '$' , // $ - '%' , // % - '&' , // & - '\'' , // ' - '(' , // ( - // S6 30 - 37 - '|' , // Backslash - '~' , // POND MARK - '=' , // YEN - ' ' , // SPACE - ' ' , // ¶ - ')' , // ) - '<' , // < - '>' , // > - // S7 38 - 3F - CLRKEY , // CLR - END. - Clear display. - CURHOMEKEY, // HOME. - Cursor to home. - PAGEUP , // PAGE UP - CURSOR UP - PAGEDOWN , // PAGE DOWN - CURSOR DOWN - ENDKEY , // END - CURSOR RIGHT - HOMEKEY , // HOME - CURSOR LEFT - '?' , // ? - Question Mark - '/' , // / - Forward Slash - // S8 40 - 47 - modifier keys. - BREAKKEY , // BREAK - Shift+BREAK = BREAK - NOKEY , // CTRL - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , // SHIFT - // S9 48 - 4F - Function keys. - FUNC6 , // Function key F1 - FUNC7 , // Function key F2 - FUNC8 , // Function key F3 - FUNC9 , // Function key F4 - FUNC10 , // Function key F5 - NOKEY , - NOKEY , - NOKEY - }}, - // CONTROL CODE - {{ - // S0 00 - 07 - ESC , // SPARE - Allocate as Escape - DEBUGKEY , // GRAPH - Enable debugging output. - CTRL_CAPPA , // ^ - ANSITGLKEY, // ALPHA - Toggle Ansi terminal emulator. - NOKEY , // NO - NOKEY , // ; - NOKEY , // : - NOKEY , // CR - // S1 08 - 0F - CTRL_Y , // ^Y E3 - CTRL_Z , // ^Z E4 (CHECKER) - CTRL_AT , // ^@ - CTRL_LB , // ^[ EB/E5 - CTRL_RB , // ^] EA/E7 - NOKEY , // #NULL - NOKEY , // #NULL - NOKEY , // #NULL - // S2 10 - 17 - CTRL_Q , // ^Q - CTRL_R , // ^R - CTRL_S , // ^S - CTRL_T , // ^T - CTRL_U , // ^U - CTRL_V , // ^V - CTRL_W , // ^W E1 - CTRL_X , // ^X E2 - // S3 18 - 1F - CTRL_I , // ^I F9 - CTRL_J , // ^J FA - CTRL_K , // ^K FB - CTRL_L , // ^L FC - CTRL_M , // ^M CD - CTRL_N , // ^N FE - CTRL_O , // ^O FF - CTRL_P , // ^P E0 - // S4 20 - 27 - CTRL_A , // ^A F1 - CTRL_B , // ^B F2 - CTRL_C , // ^C F3 - CTRL_D , // ^D F4 - CTRL_E , // ^E F5 - CTRL_F , // ^F F6 - CTRL_G , // ^G F7 - CTRL_H , // ^H F8 - // S5 28 - 2F - HOTKEY_ORIGINAL, // 1 - Hotkey to invoke original mode. - HOTKEY_RFS40, // 2 - Hotkey to invoke RFS 40 mode. - HOTKEY_TZFS, // 3 - Hotkey to invoke TZFS mode. - HOTKEY_LINUX, // 4 - Hotkey to invoke Linux mode. - NOKEY , - NOKEY , - NOKEY , - NOKEY , - // S6 30 - 37 (ERROR? 7 VALUES ONLY!!) - NOKEY , // ^YEN E6 - CTRL_CAPPA , // ^ EF - NOKEY , - NOKEY , - NOKEY , - CTRL_UNDSCR , // ^, - NOKEY , - NOKEY , - // S7 - 38 - 3F - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , - CTRL_SLASH , // ^/ EE - // S8 40 - 47 - modifier keys. - NOKEY , // BREAK - CTRL+BREAK - not yet assigned - NOKEY , // CTRL - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , // SHIFT - // S9 48 - 4F - Function keys. - FUNC1 , // Function key F1 - FUNC2 , // Function key F2 - FUNC3 , // Function key F3 - FUNC4 , // Function key F4 - FUNC5 , // Function key F5 - NOKEY , - NOKEY , - NOKEY - }}, - // KANA - {{ - // S0 00 - 07 - 0xBF , // SPARE - NOKEY , // GRAPH BUT NULL - 0xCF , // NIKO WH. - 0xC9 , // ALPHA - NOKEY , // NO - 0xB5 , // MO - 0x4D , // DAKU TEN - 0xCD , // CR - // S1 08 - 0F - 0x35 , // HA - 0x77 , // TA - 0xD7 , // WA - 0xB3 , // YO - 0xB7 , // HANDAKU - NOKEY , - NOKEY , - NOKEY , - // S2 10 - 17 - 0x7C , // KA - 0x70 , // KE - 0x41 , // SHI - 0x31 , // KO - 0x39 , // HI - 0xA6 , // TE - 0x78 , // KI - 0xDD , // CHI - // S3 18 - 1F - 0x3D , // FU - 0x5D , // MI - 0x6C , // MU - 0x56 , // ME - 0x1D , // RHI - 0x33 , // RA - 0xD5 , // HE - 0xB1 , // HO - // S4 20 - 27 - 0x46 , // SA - 0x6E , // TO - 0xD9 , // THU - 0x48 , // SU - 0x74 , // KU - 0x43 , // SE - 0x4C , // SO - 0x73 , // MA - // S5 28 - 2F - 0x3F , // A - 0x36 , // I - 0x7E , // U - 0x3B , // E - 0x7A , // O - 0x1E , // NA - 0x5F , // NI - 0xA2 , // NU - // S6 30 - 37 - 0xD3 , // YO - 0x9F , // YU - 0xD1 , // YA - 0x00 , // SPACE - 0x9D , // NO - 0xA3 , // NE - 0xD0 , // RU - 0xB9 , // RE - // S7 38 - 3F - 0xC6 , // ?CLR - 0xC5 , // ?HOME - 0xC2 , // ?CURSOR UP - 0xC1 , // ?CURSOR DOWN - 0xC3 , // ?CURSOR RIGHT - 0xC4 , // ?CURSOR LEFT - 0xBB , // DASH - 0xBE , // RO - // S8 40 - 47 - modifier keys. - NOKEY , // BREAK - GRPH+BREAK - not yet assigned - NOKEY , // CTRL - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , - NOKEY , // SHIFT - // S9 48 - 4F - Function keys. - FUNC1 , // Function key F1 - FUNC2 , // Function key F2 - FUNC3 , // Function key F3 - FUNC4 , // Function key F4 - FUNC5 , // Function key F5 - NOKEY , - NOKEY , - NOKEY - }} -}; - -#elif (TARGET_HOST_MZ80A == 1) +#if (TARGET_HOST_MZ80A == 1) static t_scanCodeMap scanCodeMap[] = { // MZ_80A NO SHIFT {{ @@ -1153,6 +817,945 @@ static t_scanCodeMap scanCodeMap[] = { }} }; +#elif (TARGET_HOST_MZ700 == 1) +static t_scanCodeMap scanCodeMap[] = { + // NO SHIFT + {{ + // S0 00 - 07 + ESC , // SPARE - Allocate as Escape + GRAPHKEY , // GRAPH + '_' , // Pound/Down Arrow + ALPHAKEY , // ALPHA + NOKEY , // NO + ';' , // + + ':' , // * + CR , // CR + // S1 08 - 0F + 'y' , // y + 'z' , // z + '@' , // ` + '[' , // { + ']' , // } + NOKEY , // NULL + NOKEY , // NULL + NOKEY , // NULL + // S2 10 - 17 + 'q' , // q + 'r' , // r + 's' , // s + 't' , // t + 'u' , // u + 'v' , // v + 'w' , // w + 'x' , // x + // S3 18 - 1F + 'i' , // i + 'j' , // j + 'k' , // k + 'l' , // l + 'm' , // m + 'n' , // n + 'o' , // o + 'p' , // p + // S4 20 - 27 + 'a' , // a + 'b' , // b + 'c' , // c + 'd' , // d + 'e' , // e + 'f' , // f + 'g' , // g + 'h' , // h + // S5 28 - 2F + '1' , // 1 + '2' , // 2 + '3' , // 3 + '4' , // 4 + '5' , // 5 + '6' , // 6 + '7' , // 7 + '8' , // 8 + // S6 30 - 37 + '\\' , // Backslash + CURSUP , // + '-' , // - + ' ' , // SPACE + '0' , // 0 + '9' , // 9 + ',' , // , + '.' , // . + // S7 38 - 3F + INSERT , // INST. + DELETE , // DEL. + CURSUP , // CURSOR UP + CURSDOWN , // CURSOR DOWN + CURSRIGHT, // CURSOR RIGHT + CURSLEFT , // CURSOR LEFT + '?' , // Question Mark + '/' , // Forward Slash + // S8 40 - 47 - modifier keys. + BACKS , // BREAK - Backspace without modifiers, like standard ascii keyboards. + NOKEY , // CTRL + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , // SHIFT + // S9 48 - 4F - Function keys. + FUNC1 , // Function key F1 + FUNC2 , // Function key F2 + FUNC3 , // Function key F3 + FUNC4 , // Function key F4 + FUNC5 , // Function key F5 + NOKEY , + NOKEY , + NOKEY + }}, + // CAPS LOCK + {{ + // S0 00 - 07 + ESC , // SPARE - Allocate as Escape + GRAPHKEY , // GRAPH + 0x58 , // + ALPHAKEY , // ALPHA + NOKEY , // NO + ':' , // ; + ';' , // : + CR , // CR + // S1 08 - 0F + 'Y' , // Y + 'Z' , // Z + '@' , // @ + '[' , // [ + ']' , // ] + NOKEY , // NULL + NOKEY , // NULL + NOKEY , // NULL + // S2 10 - 17 + 'Q' , // Q + 'R' , // R + 'S' , // S + 'T' , // T + 'U' , // U + 'V' , // V + 'W' , // W + 'X' , // X + // S3 18 - 1F + 'I' , // I + 'J' , // J + 'K' , // K + 'L' , // L + 'M' , // M + 'N' , // N + 'O' , // O + 'P' , // P + // S4 20 - 27 + 'A' , // A + 'B' , // B + 'C' , // C + 'D' , // D + 'E' , // E + 'F' , // F + 'G' , // G + 'H' , // H + // S5 28 - 2F + '1' , // 1 + '2' , // 2 + '3' , // 3 + '4' , // 4 + '5' , // 5 + '6' , // 6 + '7' , // 7 + '8' , // 8 + // S6 30 - 37 + '\\' , // Backslash + CURSUP , // + '-' , // - + ' ' , // SPACE + '0' , // 0 + '9' , // 9 + ',' , // , + '.' , // . + // S7 38 - 3F + INSERT , // INST. + DELETE , // DEL. + CURSUP , // CURSOR UP + CURSDOWN , // CURSOR DOWN + CURSRIGHT, // CURSOR RIGHT + CURSLEFT , // CURSOR LEFT + '?' , // ? + '/' , // / + // S8 40 - 47 - modifier keys. + BACKS , // BREAK - Backspace without modifiers, like standard ascii keyboards. + NOKEY , // CTRL + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , // SHIFT + // S9 48 - 4F - Function keys. + FUNC1 , // Function key F1 + FUNC2 , // Function key F2 + FUNC3 , // Function key F3 + FUNC4 , // Function key F4 + FUNC5 , // Function key F5 + NOKEY , + NOKEY , + NOKEY + }}, + // SHIFT LOCK. + {{ + // S0 00 - 07 + ESC , // SPARE - Allocate as Escape + GRAPHKEY , // GRAPH + 0x58 , // + ALPHAKEY , // ALPHA + NOKEY , // NO + '+' , // ; + '*' , // : + CR , // CR + // S1 08 - 0F + 'Y' , // Y + 'Z' , // Z + '`' , // @ + '{' , // [ + '}' , // ] + NOKEY , // NULL + NOKEY , // NULL + NOKEY , // NULL + // S2 10 - 17 + 'Q' , // Q + 'R' , // R + 'S' , // S + 'T' , // T + 'U' , // U + 'V' , // V + 'W' , // W + 'X' , // X + // S3 18 - 1F + 'I' , // I + 'J' , // J + 'K' , // K + 'L' , // L + 'M' , // M + 'N' , // N + 'O' , // O + 'P' , // P + // S4 20 - 27 + 'A' , // A + 'B' , // B + 'C' , // C + 'D' , // D + 'E' , // E + 'F' , // F + 'G' , // G + 'H' , // H + // S5 28 - 2F + '!' , // ! + '"' , // " + '#' , // # + '$' , // $ + '%' , // % + '&' , // & + '\'' , // ' + '(' , // ( + // S6 30 - 37 + '|' , // Backslash + '~' , // POND MARK + '=' , // YEN + ' ' , // SPACE + ' ' , // ¶ + ')' , // ) + '<' , // < + '>' , // > + // S7 38 - 3F + CLRKEY , // CLR - END. - Clear display. + CURHOMEKEY, // HOME. - Cursor to home. + PAGEUP , // PAGE UP - CURSOR UP + PAGEDOWN , // PAGE DOWN - CURSOR DOWN + ENDKEY , // END - CURSOR RIGHT + HOMEKEY , // HOME - CURSOR LEFT + '?' , // ? - Question Mark + '/' , // / - Forward Slash + // S8 40 - 47 - modifier keys. + BREAKKEY , // BREAK - Shift+BREAK = BREAK + NOKEY , // CTRL + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , // SHIFT + // S9 48 - 4F - Function keys. + FUNC6 , // Function key F1 + FUNC7 , // Function key F2 + FUNC8 , // Function key F3 + FUNC9 , // Function key F4 + FUNC10 , // Function key F5 + NOKEY , + NOKEY , + NOKEY + }}, + // CONTROL CODE + {{ + // S0 00 - 07 + ESC , // SPARE - Allocate as Escape + DEBUGKEY , // GRAPH - Enable debugging output. + CTRL_CAPPA , // ^ + ANSITGLKEY, // ALPHA - Toggle Ansi terminal emulator. + NOKEY , // NO + NOKEY , // ; + NOKEY , // : + NOKEY , // CR + // S1 08 - 0F + CTRL_Y , // ^Y E3 + CTRL_Z , // ^Z E4 (CHECKER) + CTRL_AT , // ^@ + CTRL_LB , // ^[ EB/E5 + CTRL_RB , // ^] EA/E7 + NOKEY , // #NULL + NOKEY , // #NULL + NOKEY , // #NULL + // S2 10 - 17 + CTRL_Q , // ^Q + CTRL_R , // ^R + CTRL_S , // ^S + CTRL_T , // ^T + CTRL_U , // ^U + CTRL_V , // ^V + CTRL_W , // ^W E1 + CTRL_X , // ^X E2 + // S3 18 - 1F + CTRL_I , // ^I F9 + CTRL_J , // ^J FA + CTRL_K , // ^K FB + CTRL_L , // ^L FC + CTRL_M , // ^M CD + CTRL_N , // ^N FE + CTRL_O , // ^O FF + CTRL_P , // ^P E0 + // S4 20 - 27 + CTRL_A , // ^A F1 + CTRL_B , // ^B F2 + CTRL_C , // ^C F3 + CTRL_D , // ^D F4 + CTRL_E , // ^E F5 + CTRL_F , // ^F F6 + CTRL_G , // ^G F7 + CTRL_H , // ^H F8 + // S5 28 - 2F + HOTKEY_ORIGINAL, // 1 - Hotkey to invoke original mode. + HOTKEY_RFS40, // 2 - Hotkey to invoke RFS 40 mode. + HOTKEY_TZFS, // 3 - Hotkey to invoke TZFS mode. + HOTKEY_LINUX, // 4 - Hotkey to invoke Linux mode. + NOKEY , + NOKEY , + NOKEY , + NOKEY , + // S6 30 - 37 (ERROR? 7 VALUES ONLY!!) + NOKEY , // ^YEN E6 + CTRL_CAPPA , // ^ EF + NOKEY , + NOKEY , + NOKEY , + CTRL_UNDSCR , // ^, + NOKEY , + NOKEY , + // S7 - 38 - 3F + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + CTRL_SLASH , // ^/ EE + // S8 40 - 47 - modifier keys. + NOKEY , // BREAK - CTRL+BREAK - not yet assigned + NOKEY , // CTRL + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , // SHIFT + // S9 48 - 4F - Function keys. + FUNC1 , // Function key F1 + FUNC2 , // Function key F2 + FUNC3 , // Function key F3 + FUNC4 , // Function key F4 + FUNC5 , // Function key F5 + NOKEY , + NOKEY , + NOKEY + }}, + // KANA + {{ + // S0 00 - 07 + 0xBF , // SPARE + GRAPHKEY , // GRAPH + 0xCF , // NIKO WH. + 0xC9 , // ALPHA + NOKEY , // NO + 0xB5 , // MO + 0x4D , // DAKU TEN + 0xCD , // CR + // S1 08 - 0F + 0x35 , // HA + 0x77 , // TA + 0xD7 , // WA + 0xB3 , // YO + 0xB7 , // HANDAKU + NOKEY , + NOKEY , + NOKEY , + // S2 10 - 17 + 0x7C , // KA + 0x70 , // KE + 0x41 , // SHI + 0x31 , // KO + 0x39 , // HI + 0xA6 , // TE + 0x78 , // KI + 0xDD , // CHI + // S3 18 - 1F + 0x3D , // FU + 0x5D , // MI + 0x6C , // MU + 0x56 , // ME + 0x1D , // RHI + 0x33 , // RA + 0xD5 , // HE + 0xB1 , // HO + // S4 20 - 27 + 0x46 , // SA + 0x6E , // TO + 0xD9 , // THU + 0x48 , // SU + 0x74 , // KU + 0x43 , // SE + 0x4C , // SO + 0x73 , // MA + // S5 28 - 2F + 0x3F , // A + 0x36 , // I + 0x7E , // U + 0x3B , // E + 0x7A , // O + 0x1E , // NA + 0x5F , // NI + 0xA2 , // NU + // S6 30 - 37 + 0xD3 , // YO + 0x9F , // YU + 0xD1 , // YA + 0x00 , // SPACE + 0x9D , // NO + 0xA3 , // NE + 0xD0 , // RU + 0xB9 , // RE + // S7 38 - 3F + 0xC6 , // ?CLR + 0xC5 , // ?HOME + 0xC2 , // ?CURSOR UP + 0xC1 , // ?CURSOR DOWN + 0xC3 , // ?CURSOR RIGHT + 0xC4 , // ?CURSOR LEFT + 0xBB , // DASH + 0xBE , // RO + // S8 40 - 47 - modifier keys. + NOKEY , // BREAK - GRPH+BREAK - not yet assigned + NOKEY , // CTRL + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , // SHIFT + // S9 48 - 4F - Function keys. + FUNC1 , // Function key F1 + FUNC2 , // Function key F2 + FUNC3 , // Function key F3 + FUNC4 , // Function key F4 + FUNC5 , // Function key F5 + NOKEY , + NOKEY , + NOKEY + }} +}; + + +#elif (TARGET_HOST_MZ1500 == 1) +static t_scanCodeMap scanCodeMap[] = { + // NO SHIFT + {{ + // S0 00 - 07 + ESC , // SPARE - Allocate as Escape + GRAPHKEY , // GRAPH + '_' , // Pound/Down Arrow + ALPHAKEY , // ALPHA + NOKEY , // NO + ';' , // + + ':' , // * + CR , // CR + // S1 08 - 0F + 'y' , // y + 'z' , // z + '@' , // ` + '[' , // { + ']' , // } + NOKEY , // NULL + NOKEY , // NULL + NOKEY , // NULL + // S2 10 - 17 + 'q' , // q + 'r' , // r + 's' , // s + 't' , // t + 'u' , // u + 'v' , // v + 'w' , // w + 'x' , // x + // S3 18 - 1F + 'i' , // i + 'j' , // j + 'k' , // k + 'l' , // l + 'm' , // m + 'n' , // n + 'o' , // o + 'p' , // p + // S4 20 - 27 + 'a' , // a + 'b' , // b + 'c' , // c + 'd' , // d + 'e' , // e + 'f' , // f + 'g' , // g + 'h' , // h + // S5 28 - 2F + '1' , // 1 + '2' , // 2 + '3' , // 3 + '4' , // 4 + '5' , // 5 + '6' , // 6 + '7' , // 7 + '8' , // 8 + // S6 30 - 37 + '\\' , // Backslash + CURSUP , // + '-' , // - + ' ' , // SPACE + '0' , // 0 + '9' , // 9 + ',' , // , + '.' , // . + // S7 38 - 3F + INSERT , // INST. + DELETE , // DEL. + CURSUP , // CURSOR UP + CURSDOWN , // CURSOR DOWN + CURSRIGHT, // CURSOR RIGHT + CURSLEFT , // CURSOR LEFT + '?' , // Question Mark + '/' , // Forward Slash + // S8 40 - 47 - modifier keys. + BACKS , // BREAK - Backspace without modifiers, like standard ascii keyboards. + NOKEY , // CTRL + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , // SHIFT + // S9 48 - 4F - Function keys. + FUNC1 , // Function key F1 + FUNC2 , // Function key F2 + FUNC3 , // Function key F3 + FUNC4 , // Function key F4 + FUNC5 , // Function key F5 + NOKEY , + NOKEY , + NOKEY + }}, + // CAPS LOCK + {{ + // S0 00 - 07 + ESC , // SPARE - Allocate as Escape + GRAPHKEY , // GRAPH + 0x58 , // + ALPHAKEY , // ALPHA + NOKEY , // NO + ':' , // ; + ';' , // : + CR , // CR + // S1 08 - 0F + 'Y' , // Y + 'Z' , // Z + '@' , // @ + '[' , // [ + ']' , // ] + NOKEY , // NULL + NOKEY , // NULL + NOKEY , // NULL + // S2 10 - 17 + 'Q' , // Q + 'R' , // R + 'S' , // S + 'T' , // T + 'U' , // U + 'V' , // V + 'W' , // W + 'X' , // X + // S3 18 - 1F + 'I' , // I + 'J' , // J + 'K' , // K + 'L' , // L + 'M' , // M + 'N' , // N + 'O' , // O + 'P' , // P + // S4 20 - 27 + 'A' , // A + 'B' , // B + 'C' , // C + 'D' , // D + 'E' , // E + 'F' , // F + 'G' , // G + 'H' , // H + // S5 28 - 2F + '1' , // 1 + '2' , // 2 + '3' , // 3 + '4' , // 4 + '5' , // 5 + '6' , // 6 + '7' , // 7 + '8' , // 8 + // S6 30 - 37 + '\\' , // Backslash + CURSUP , // + '-' , // - + ' ' , // SPACE + '0' , // 0 + '9' , // 9 + ',' , // , + '.' , // . + // S7 38 - 3F + INSERT , // INST. + DELETE , // DEL. + CURSUP , // CURSOR UP + CURSDOWN , // CURSOR DOWN + CURSRIGHT, // CURSOR RIGHT + CURSLEFT , // CURSOR LEFT + '?' , // ? + '/' , // / + // S8 40 - 47 - modifier keys. + BACKS , // BREAK - Backspace without modifiers, like standard ascii keyboards. + NOKEY , // CTRL + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , // SHIFT + // S9 48 - 4F - Function keys. + FUNC1 , // Function key F1 + FUNC2 , // Function key F2 + FUNC3 , // Function key F3 + FUNC4 , // Function key F4 + FUNC5 , // Function key F5 + NOKEY , + NOKEY , + NOKEY + }}, + // SHIFT LOCK. + {{ + // S0 00 - 07 + ESC , // SPARE - Allocate as Escape + GRAPHKEY , // GRAPH + 0x58 , // + ALPHAKEY , // ALPHA + NOKEY , // NO + '+' , // ; + '*' , // : + CR , // CR + // S1 08 - 0F + 'Y' , // Y + 'Z' , // Z + '`' , // @ + '{' , // [ + '}' , // ] + NOKEY , // NULL + NOKEY , // NULL + NOKEY , // NULL + // S2 10 - 17 + 'Q' , // Q + 'R' , // R + 'S' , // S + 'T' , // T + 'U' , // U + 'V' , // V + 'W' , // W + 'X' , // X + // S3 18 - 1F + 'I' , // I + 'J' , // J + 'K' , // K + 'L' , // L + 'M' , // M + 'N' , // N + 'O' , // O + 'P' , // P + // S4 20 - 27 + 'A' , // A + 'B' , // B + 'C' , // C + 'D' , // D + 'E' , // E + 'F' , // F + 'G' , // G + 'H' , // H + // S5 28 - 2F + '!' , // ! + '"' , // " + '#' , // # + '$' , // $ + '%' , // % + '&' , // & + '\'' , // ' + '(' , // ( + // S6 30 - 37 + '|' , // Backslash + '~' , // POND MARK + '=' , // YEN + ' ' , // SPACE + ' ' , // ¶ + ')' , // ) + '<' , // < + '>' , // > + // S7 38 - 3F + CLRKEY , // CLR - END. - Clear display. + CURHOMEKEY, // HOME. - Cursor to home. + PAGEUP , // PAGE UP - CURSOR UP + PAGEDOWN , // PAGE DOWN - CURSOR DOWN + ENDKEY , // END - CURSOR RIGHT + HOMEKEY , // HOME - CURSOR LEFT + '?' , // ? - Question Mark + '/' , // / - Forward Slash + // S8 40 - 47 - modifier keys. + BREAKKEY , // BREAK - Shift+BREAK = BREAK + NOKEY , // CTRL + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , // SHIFT + // S9 48 - 4F - Function keys. + FUNC6 , // Function key F1 + FUNC7 , // Function key F2 + FUNC8 , // Function key F3 + FUNC9 , // Function key F4 + FUNC10 , // Function key F5 + NOKEY , + NOKEY , + NOKEY + }}, + // CONTROL CODE + {{ + // S0 00 - 07 + ESC , // SPARE - Allocate as Escape + DEBUGKEY , // GRAPH - Enable debugging output. + CTRL_CAPPA , // ^ + ANSITGLKEY, // ALPHA - Toggle Ansi terminal emulator. + NOKEY , // NO + NOKEY , // ; + NOKEY , // : + NOKEY , // CR + // S1 08 - 0F + CTRL_Y , // ^Y E3 + CTRL_Z , // ^Z E4 (CHECKER) + CTRL_AT , // ^@ + CTRL_LB , // ^[ EB/E5 + CTRL_RB , // ^] EA/E7 + NOKEY , // #NULL + NOKEY , // #NULL + NOKEY , // #NULL + // S2 10 - 17 + CTRL_Q , // ^Q + CTRL_R , // ^R + CTRL_S , // ^S + CTRL_T , // ^T + CTRL_U , // ^U + CTRL_V , // ^V + CTRL_W , // ^W E1 + CTRL_X , // ^X E2 + // S3 18 - 1F + CTRL_I , // ^I F9 + CTRL_J , // ^J FA + CTRL_K , // ^K FB + CTRL_L , // ^L FC + CTRL_M , // ^M CD + CTRL_N , // ^N FE + CTRL_O , // ^O FF + CTRL_P , // ^P E0 + // S4 20 - 27 + CTRL_A , // ^A F1 + CTRL_B , // ^B F2 + CTRL_C , // ^C F3 + CTRL_D , // ^D F4 + CTRL_E , // ^E F5 + CTRL_F , // ^F F6 + CTRL_G , // ^G F7 + CTRL_H , // ^H F8 + // S5 28 - 2F + HOTKEY_ORIGINAL, // 1 - Hotkey to invoke original mode. + HOTKEY_RFS40, // 2 - Hotkey to invoke RFS 40 mode. + HOTKEY_TZFS, // 3 - Hotkey to invoke TZFS mode. + HOTKEY_LINUX, // 4 - Hotkey to invoke Linux mode. + NOKEY , + NOKEY , + NOKEY , + NOKEY , + // S6 30 - 37 (ERROR? 7 VALUES ONLY!!) + NOKEY , // ^YEN E6 + CTRL_CAPPA , // ^ EF + NOKEY , + NOKEY , + NOKEY , + CTRL_UNDSCR , // ^, + NOKEY , + NOKEY , + // S7 - 38 - 3F + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + CTRL_SLASH , // ^/ EE + // S8 40 - 47 - modifier keys. + NOKEY , // BREAK - CTRL+BREAK - not yet assigned + NOKEY , // CTRL + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , // SHIFT + // S9 48 - 4F - Function keys. + FUNC1 , // Function key F1 + FUNC2 , // Function key F2 + FUNC3 , // Function key F3 + FUNC4 , // Function key F4 + FUNC5 , // Function key F5 + NOKEY , + NOKEY , + NOKEY + }}, + // KANA + {{ + // S0 00 - 07 + 0xBF , // SPARE + GRAPHKEY , // GRAPH + 0xCF , // NIKO WH. + 0xC9 , // ALPHA + NOKEY , // NO + 0xB5 , // MO + 0x4D , // DAKU TEN + 0xCD , // CR + // S1 08 - 0F + 0x35 , // HA + 0x77 , // TA + 0xD7 , // WA + 0xB3 , // YO + 0xB7 , // HANDAKU + NOKEY , + NOKEY , + NOKEY , + // S2 10 - 17 + 0x7C , // KA + 0x70 , // KE + 0x41 , // SHI + 0x31 , // KO + 0x39 , // HI + 0xA6 , // TE + 0x78 , // KI + 0xDD , // CHI + // S3 18 - 1F + 0x3D , // FU + 0x5D , // MI + 0x6C , // MU + 0x56 , // ME + 0x1D , // RHI + 0x33 , // RA + 0xD5 , // HE + 0xB1 , // HO + // S4 20 - 27 + 0x46 , // SA + 0x6E , // TO + 0xD9 , // THU + 0x48 , // SU + 0x74 , // KU + 0x43 , // SE + 0x4C , // SO + 0x73 , // MA + // S5 28 - 2F + 0x3F , // A + 0x36 , // I + 0x7E , // U + 0x3B , // E + 0x7A , // O + 0x1E , // NA + 0x5F , // NI + 0xA2 , // NU + // S6 30 - 37 + 0xD3 , // YO + 0x9F , // YU + 0xD1 , // YA + 0x00 , // SPACE + 0x9D , // NO + 0xA3 , // NE + 0xD0 , // RU + 0xB9 , // RE + // S7 38 - 3F + 0xC6 , // ?CLR + 0xC5 , // ?HOME + 0xC2 , // ?CURSOR UP + 0xC1 , // ?CURSOR DOWN + 0xC3 , // ?CURSOR RIGHT + 0xC4 , // ?CURSOR LEFT + 0xBB , // DASH + 0xBE , // RO + // S8 40 - 47 - modifier keys. + NOKEY , // BREAK - GRPH+BREAK - not yet assigned + NOKEY , // CTRL + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , + NOKEY , // SHIFT + // S9 48 - 4F - Function keys. + FUNC1 , // Function key F1 + FUNC2 , // Function key F2 + FUNC3 , // Function key F3 + FUNC4 , // Function key F4 + FUNC5 , // Function key F5 + NOKEY , + NOKEY , + NOKEY + }} +}; + #elif (TARGET_HOST_MZ2000 == 1) static t_scanCodeMap scanCodeMap[] = { // MZ_2000 NO SHIFT @@ -1741,7 +2344,35 @@ static t_ansiKeyMap ansiKeySeq[] = { { PAGEDOWN , "\x1b[6~" }, // Page Down. }; -#if (TARGET_HOST_MZ700 == 1) +#if (TARGET_HOST_MZ80A == 1) + // Static structures for controlling and managing hardware features. + // Display control structure. Used to manage the display including the Ansi Terminal. + const t_displayBuffer displayDefault = { .displayAttr = 0x71, .backingRow = 0, .displayCol = 0, .displayRow = 0, .maxBackingRow = (VC_DISPLAY_BUFFER_SIZE / VC_MAX_COLUMNS), + .maxDisplayRow = VC_MAX_ROWS, .maxBackingCol = 80, .useAnsiTerm = 1, .lineWrap = 0, .inDebug = 0 + }; + + // Keyboard control structure. Used to manage keyboard sweep, mapping and store. + const t_keyboard keyboardDefault = { .holdTimer = 0L, .autorepeat = 0, .cursorOn = 1, .flashTimer = 0L, .keyBuf[0] = 0x00, .keyBufPtr = 0, + .mode = KEYB_LOWERCASE, .dualmode = KEYB_DUAL_GRAPH + }; + + // Audio control structure. Used to manage audio output. + const t_audio audioDefault = { .audioStopTimer = 0 + }; + + + // AnsiTerminal control structure. Used to manage the inbuilt Ansi Terminal. + const t_AnsiTerm ansitermDefault = { .state = ANSITERM_ESC, .charcnt = 0, .paramcnt = 0, .setDisplayMode = 0, .setExtendedMode = 0, .saveRow = 0, .saveCol = 0, + }; + + // Module control structure. + const t_control ctrlDefault = { .suspendIO = 0, .debug = 0 + }; + + // Colour map for the Ansi Terminal. + const unsigned char ansiColourMap[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + +#elif (TARGET_HOST_MZ700 == 1) // Static structures for controlling and managing hardware features. // Display control structure. Used to manage the display including the Ansi Terminal. const t_displayBuffer displayDefault = { .displayAttr = 0x71, .backingRow = 0, .displayCol = 0, .displayRow = 0, .maxBackingRow = (VC_DISPLAY_BUFFER_SIZE / VC_MAX_COLUMNS), @@ -1767,23 +2398,21 @@ static t_ansiKeyMap ansiKeySeq[] = { // Colour map for the Ansi Terminal. const unsigned char ansiColourMap[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; -#elif (TARGET_HOST_MZ80A == 1) +#elif (TARGET_HOST_MZ1500 == 1) // Static structures for controlling and managing hardware features. // Display control structure. Used to manage the display including the Ansi Terminal. const t_displayBuffer displayDefault = { .displayAttr = 0x71, .backingRow = 0, .displayCol = 0, .displayRow = 0, .maxBackingRow = (VC_DISPLAY_BUFFER_SIZE / VC_MAX_COLUMNS), - .maxDisplayRow = VC_MAX_ROWS, .maxBackingCol = 80, .useAnsiTerm = 1, .lineWrap = 0, .inDebug = 0 + .maxDisplayRow = VC_MAX_ROWS, .maxBackingCol = 40, .useAnsiTerm = 1, .lineWrap = 0, .inDebug = 0 }; - // Keyboard control structure. Used to manage keyboard sweep, mapping and store. const t_keyboard keyboardDefault = { .holdTimer = 0L, .autorepeat = 0, .cursorOn = 1, .flashTimer = 0L, .keyBuf[0] = 0x00, .keyBufPtr = 0, - .mode = KEYB_LOWERCASE, .dualmode = KEYB_DUAL_GRAPH + .mode = KEYB_LOWERCASE, .dualmode = KEYB_DUAL_NONE }; // Audio control structure. Used to manage audio output. const t_audio audioDefault = { .audioStopTimer = 0 }; - // AnsiTerminal control structure. Used to manage the inbuilt Ansi Terminal. const t_AnsiTerm ansitermDefault = { .state = ANSITERM_ESC, .charcnt = 0, .paramcnt = 0, .setDisplayMode = 0, .setExtendedMode = 0, .saveRow = 0, .saveCol = 0, }; @@ -1841,17 +2470,17 @@ static t_ansiKeyMap ansiKeySeq[] = { uint8_t mzInitMBHardware(void) { // Locals. - #if (TARGET_HOST_MZ2000 == 1) + #if (TARGET_HOST_MZ1500 == 1 || TARGET_HOST_MZ2000 == 1) uint32_t idx; uint32_t idx2; #endif - #if (TARGET_HOST_MZ700 == 1) + #if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) // Ensure memory paging is set to default. SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR); #endif - #if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ80A == 1) + #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) // From the 1Z-013A monitor code, initialise the 8255 PIO. // WRITE_HARDWARE(1, MBADDR_KEYPF, 0x8A); // 10001010 CTRL WORD MODE0 @@ -1878,6 +2507,27 @@ uint8_t mzInitMBHardware(void) // Disable the hardware sound output. WRITE_HARDWARE(0, MBADDR_SUNDG, 0x00); // Sound could be enabled on start, disable it. + #if (TARGET_HOST_MZ1500 == 1) + for(idx=1; idx < 4; idx++) + { + WRITE_HARDWARE(0, IO_ADDR_E5, 0x00); // Select the PCG Bank. + for(idx2=0xD000; idx2 < 0xF000; idx2++) + { + WRITE_HARDWARE(0, idx2, 0x00); // Zero the PCG memory in the bank. + } + } + WRITE_HARDWARE(0, IO_ADDR_E6, 0x00); // Deselect the PCG Bank. + WRITE_HARDWARE(0, IO_PCG_PRIO, 0x00); // Set text as priority. + for(idx=0x11; idx < 0x90; idx+=0x11) + { + WRITE_HARDWARE(0, IO_PALETTE, idx); // Setup palettes. + } + for(idx=0x9F; idx <- 0xFF; idx+=0x20) + { + WRITE_HARDWARE(0, IO_PSG_BOTH, idx); // Setup PSG. + } + #endif + #elif (TARGET_HOST_MZ2000 == 1) // Initialise the Z80 PIO/8255 controllers. // @@ -1946,6 +2596,8 @@ uint8_t mzInit(void) mzSetMachineVideoMode(VMMODE_MZ80A); #elif (TARGET_HOST_MZ700 == 1) mzSetMachineVideoMode(VMMODE_MZ700); + #elif (TARGET_HOST_MZ1500 == 1) + mzSetMachineVideoMode(VMMODE_MZ1500); #elif (TARGET_HOST_MZ2000 == 1) mzSetMachineVideoMode(VMMODE_MZ2000); #endif @@ -1963,9 +2615,11 @@ void mzBeep(uint32_t freq, uint32_t timeout) uint16_t freqDiv = TIMER_8253_MZ80A_FREQ/(freq*2); #elif (TARGET_HOST_MZ700 == 1) uint16_t freqDiv = TIMER_8253_MZ700_FREQ/freq; + #elif (TARGET_HOST_MZ1500 == 1) + uint16_t freqDiv = TIMER_8253_MZ700_FREQ/freq; #endif - #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) // Setup the 8253 Timer 0 to output a sound, enable output to amplifier and set timeout. WRITE_HARDWARE(0, MBADDR_CONTF, 0x34 ); // Timer 0 to square wave generator, load LSB first. WRITE_HARDWARE(0, MBADDR_CONT0, (freqDiv&0xff) ); @@ -2058,7 +2712,7 @@ void mzClearDisplay(uint8_t mode, uint8_t updPos) for(dstVRAMAddr=dstVRAMStartAddr, dstARAMAddr = dstARAMStartAddr; dstVRAMAddr <= dstVRAMEndAddr; dstVRAMAddr+=1, dstARAMAddr+=1) { // Clear both Video and Attribute RAM. - WRITE_VRAM_CHAR(dstVRAMAddr, 0x00); + WRITE_VRAM_CHAR(dstVRAMAddr, 0x00, 0); WRITE_VRAM_ATTRIBUTE(dstARAMAddr, display.displayAttr); } // Clear the shadow display scrollback RAM. @@ -2112,7 +2766,7 @@ void mzClearLine(int row, int colStart, int colEnd, uint8_t updPos) // for(dstVRAMAddr=dstVRAMStartAddr, dstARAMAddr = dstARAMStartAddr; dstVRAMAddr <= dstVRAMEndAddr; dstVRAMAddr+=1, dstARAMAddr+=1) { - WRITE_VRAM_CHAR(dstVRAMAddr, 0x00); + WRITE_VRAM_CHAR(dstVRAMAddr, 0x00, 0); WRITE_VRAM_ATTRIBUTE(dstARAMAddr, display.displayAttr); } @@ -2169,11 +2823,13 @@ uint8_t mzSetDisplayWidth(uint8_t width) return(1); // Toggle the 40/80 bit according to requirements. + #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ2000 == 1) if(width == 40) { + #endif display.maxBackingCol = 40; - #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + #if (TARGET_HOST_MZ80A == 1) // Dummy read to enable access to control register. READ_HARDWARE_INIT(0, MBADDR_DSPCTL); WRITE_HARDWARE(0, MBADDR_DSPCTL, 0x00); @@ -2182,12 +2838,14 @@ uint8_t mzSetDisplayWidth(uint8_t width) display.hwVideoMode = display.hwVideoMode & 0xDF; DISABLE_VIDEO(); #endif + + #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ2000 == 1) } else { display.maxBackingCol = 80; - #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + #if (TARGET_HOST_MZ80A == 1) // Dummy read to enable access to control register. READ_HARDWARE_INIT(0, MBADDR_DSPCTL); WRITE_HARDWARE(0, MBADDR_DSPCTL, VMMODE_80CHAR); @@ -2197,6 +2855,7 @@ uint8_t mzSetDisplayWidth(uint8_t width) DISABLE_VIDEO(); #endif } + #endif return(0); } @@ -2217,7 +2876,7 @@ void mzRefreshDisplay(void) startIdx = (display.backingRow < display.maxDisplayRow ? 0 : (display.backingRow - display.maxDisplayRow)+1) * display.maxBackingCol; for(srcIdx = startIdx, dstVRAMAddr = VIDEO_VRAM_BASE_ADDR, dstARAMAddr = VIDEO_ARAM_BASE_ADDR; srcIdx < startIdx+(display.maxDisplayRow*display.maxBackingCol); srcIdx++, dstVRAMAddr++, dstARAMAddr++) { - WRITE_VRAM_CHAR(dstVRAMAddr, display.displayCharBuf[srcIdx]); + WRITE_VRAM_CHAR(dstVRAMAddr, display.displayCharBuf[srcIdx], 1); WRITE_VRAM_ATTRIBUTE(dstARAMAddr, display.displayAttrBuf[srcIdx]); } @@ -2542,7 +3201,7 @@ int mzPutChar(char c) // Output character using default attributes. dispMemAddr = VIDEO_VRAM_BASE_ADDR + (display.displayRow * display.maxBackingCol) + display.displayCol; - WRITE_VRAM_CHAR(dispMemAddr, (char)c); + WRITE_VRAM_CHAR(dispMemAddr, (char)c, 1); display.displayCharBuf[(display.backingRow * display.maxBackingCol) + display.displayCol] = c; // dispMemAddr = VIDEO_ARAM_BASE_ADDR + (display.displayRow * display.maxBackingCol) + display.displayCol; @@ -2598,7 +3257,7 @@ int mzPutRaw(char c) // Output character using default attributes. dispMemAddr = VIDEO_VRAM_BASE_ADDR + (display.displayRow * display.maxBackingCol) + display.displayCol; - WRITE_VRAM_CHAR(dispMemAddr, (char)c); + WRITE_VRAM_CHAR(dispMemAddr, (char)c, 1); display.displayCharBuf[(display.backingRow * display.maxBackingCol) + display.displayCol] = c; // dispMemAddr = VIDEO_ARAM_BASE_ADDR + (display.displayRow * display.maxBackingCol) + display.displayCol; @@ -3502,7 +4161,7 @@ uint8_t mzFlashCursor(enum CURSOR_STATES state) // Only restore character if it had been previously saved and active. if(keyboard.cursorOn == 1 && keyboard.displayCursor == 1) { - WRITE_VRAM_CHAR(dispMemAddr, display.displayCharBuf[srcIdx]); + WRITE_VRAM_CHAR(dispMemAddr, display.displayCharBuf[srcIdx], 1); } keyboard.cursorOn = 0; keyboard.displayCursor = 0; @@ -3518,7 +4177,7 @@ uint8_t mzFlashCursor(enum CURSOR_STATES state) case CURSOR_RESTORE: if(keyboard.displayCursor == 1) { - WRITE_VRAM_CHAR(dispMemAddr, display.displayCharBuf[srcIdx]); + WRITE_VRAM_CHAR(dispMemAddr, display.displayCharBuf[srcIdx], 1); keyboard.displayCursor = 0; } break; @@ -3547,10 +4206,10 @@ uint8_t mzFlashCursor(enum CURSOR_STATES state) cursorChr = CURSOR_CHR_GRAPH; break; } - WRITE_VRAM_CHAR(dispMemAddr, cursorChr); + WRITE_VRAM_CHAR(dispMemAddr, cursorChr, 0); } else { - WRITE_VRAM_CHAR(dispMemAddr, display.displayCharBuf[srcIdx]); + WRITE_VRAM_CHAR(dispMemAddr, display.displayCharBuf[srcIdx], 1); } } break; @@ -3650,7 +4309,32 @@ uint8_t mzSweepKeys(void) keyboard.scanbuf[1][strobeIdx] = keyboard.scanbuf[0][strobeIdx]; } - #if (TARGET_HOST_MZ700 == 1) + #if (TARGET_HOST_MZ80A == 1) + // Check for modifiers. + // + if((keyboard.scanbuf[0][0] & 0x01) == 0) + { + keyboard.shiftKey = 1; + } else + { + keyboard.shiftKey = 0; + } + if((keyboard.scanbuf[0][0] & 0x80) == 0 && keyboard.shiftKey == 0) + { + keyboard.ctrlKey = 1; + } else + { + keyboard.ctrlKey = 0; + } + if((keyboard.scanbuf[0][0] & 0x80) == 0 && keyboard.shiftKey == 1) + { + keyboard.breakKey = 1; + } else + { + keyboard.breakKey = 0; + } + + #elif (TARGET_HOST_MZ700 == 1) // Check for modifiers. // if((keyboard.scanbuf[0][8] & 0x80) == 0) @@ -3675,29 +4359,29 @@ uint8_t mzSweepKeys(void) keyboard.shiftKey = 0; } - #elif (TARGET_HOST_MZ80A == 1) + #elif (TARGET_HOST_MZ1500 == 1) // Check for modifiers. // - if((keyboard.scanbuf[0][0] & 0x01) == 0) + if((keyboard.scanbuf[0][8] & 0x80) == 0) { - keyboard.shiftKey = 1; + keyboard.breakKey = 1; } else { - keyboard.shiftKey = 0; + keyboard.breakKey = 0; } - if((keyboard.scanbuf[0][0] & 0x80) == 0 && keyboard.shiftKey == 0) + if((keyboard.scanbuf[0][8] & 0x40) == 0) { keyboard.ctrlKey = 1; } else { keyboard.ctrlKey = 0; } - if((keyboard.scanbuf[0][0] & 0x80) == 0 && keyboard.shiftKey == 1) + if((keyboard.scanbuf[0][8] & 0x01) == 0) { - keyboard.breakKey = 1; + keyboard.shiftKey = 1; } else { - keyboard.breakKey = 0; + keyboard.shiftKey = 0; } #elif (TARGET_HOST_MZ2000 == 1) diff --git a/software/FusionX/src/ttymz/sharpmz.h b/software/FusionX/src/ttymz/sharpmz.h index 043d225dc..050c96279 100755 --- a/software/FusionX/src/ttymz/sharpmz.h +++ b/software/FusionX/src/ttymz/sharpmz.h @@ -12,6 +12,8 @@ // Copyright: (c) 2019-2023 Philip Smart // // History: v1.0 Feb 2023 - Initial write of the Sharp MZ series hardware interface software. +// v1.01 Mar 2023 - Bug fixes and additional ESC sequence processing. +// v1.02 May 2023 - Updates to accommodate MZ-1500 host. // // Notes: See Makefile to enable/disable conditional components // @@ -37,36 +39,47 @@ #endif // Build time target. Overrides if compile time definition given. -#if defined(TARGET_HOST_MZ700) - #define TARGET_HOST_MZ700 1 - #define TARGET_HOST_MZ2000 0 - #define TARGET_HOST_MZ80A 0 - #define TARGET_HOST_PCW 0 -#elif defined(TARGET_HOST_MZ2000) - #define TARGET_HOST_MZ2000 1 - #define TARGET_HOST_MZ700 0 - #define TARGET_HOST_MZ80A 0 - #define TARGET_HOST_PCW 0 -#elif defined(TARGET_HOST_MZ80A) +#if defined(TARGET_HOST_MZ80A) #define TARGET_HOST_MZ80A 1 #define TARGET_HOST_MZ2000 0 #define TARGET_HOST_MZ700 0 + #define TARGET_HOST_MZ1500 0 + #define TARGET_HOST_PCW 0 +#elif defined(TARGET_HOST_MZ700) + #define TARGET_HOST_MZ700 1 + #define TARGET_HOST_MZ80A 0 + #define TARGET_HOST_MZ1500 0 + #define TARGET_HOST_MZ2000 0 + #define TARGET_HOST_PCW 0 +#elif defined(TARGET_HOST_MZ1500) + #define TARGET_HOST_MZ1500 1 + #define TARGET_HOST_MZ80A 0 + #define TARGET_HOST_MZ700 0 + #define TARGET_HOST_MZ2000 0 + #define TARGET_HOST_PCW 0 +#elif defined(TARGET_HOST_MZ2000) + #define TARGET_HOST_MZ2000 1 + #define TARGET_HOST_MZ80A 0 + #define TARGET_HOST_MZ700 0 + #define TARGET_HOST_MZ1500 0 #define TARGET_HOST_PCW 0 #elif defined(TARGET_HOST_PCW8XXX) || defined(TARGET_HOST_PCW9XXX) #define TARGET_HOST_PCW 1 - #define TARGET_HOST_MZ2000 0 - #define TARGET_HOST_MZ700 0 #define TARGET_HOST_MZ80A 0 + #define TARGET_HOST_MZ700 0 + #define TARGET_HOST_MZ1500 0 + #define TARGET_HOST_MZ2000 0 #else #define TARGET_HOST_MZ700 0 // Target compilation for an MZ700 - #define TARGET_HOST_MZ2000 0 // MZ2000 #define TARGET_HOST_MZ80A 0 // MZ80A + #define TARGET_HOST_MZ1500 0 // MZ1500 + #define TARGET_HOST_MZ2000 0 // MZ2000 #define TARGET_HOST_PCW 0 // Amstrad PCW8XXX/9XXX #endif // Video display constants. #define VC_MAX_ROWS 25 // Maximum number of rows on display. -#if (TARGET_HOST_MZ700 == 1) +#if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) #define VC_MAX_COLUMNS 40 // Maximum number of columns on display. #else #define VC_MAX_COLUMNS 80 // Maximum number of columns on display. @@ -79,12 +92,12 @@ #define KEYB_AUTOREPEAT_TIME 100 // Time in milliseconds between auto repeating characters. #define KEYB_FLASH_TIME 350 // Time in milliseconds for the cursor flash change. #define MAX_KEYB_BUFFER_SIZE 32 // Maximum size of the keyboard buffer. -#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) +#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) #define KEY_SCAN_ROWS 10 // Number of rows on keyboard to scan. #define CURSOR_CHR_THICK_BLOCK 0x43 // Thick block cursor for Shift Lock. - #define CURSOR_CHR_BLOCK 0xEF // Block cursor for CAPS Lock. + #define CURSOR_CHR_BLOCK 0xD0 // Block cursor for CAPS Lock. #define CURSOR_CHR_GRAPH 0xFF // Graphic cursor for GRAPH mode. - #define CURSOR_CHR_UNDERLINE 0x3E // Underline for lower case CAPS OFF. + #define CURSOR_CHR_UNDERLINE 0x3C // Underline for lower case CAPS OFF. #elif (TARGET_HOST_MZ2000 == 1) #define KEY_SCAN_ROWS 12 #define CURSOR_CHR_THICK_BLOCK 0x1E // Thick block cursor for Shift Lock. @@ -96,6 +109,7 @@ // Audio constants. #define TIMER_8253_MZ80A_FREQ 2000000 // Base input frequency of Timer 0 for square wave generation. #define TIMER_8253_MZ700_FREQ 768000 // Base input frequency of Timer 0 for square wave generation. +#define TIMER_8253_MZ1500_FREQ 768000 // Base input frequency of Timer 0 for square wave generation. // Base addresses and sizes within the Video Controller. #define VIDEO_BASE_ADDR 0x000000 // Base address of the Video Controller. @@ -165,6 +179,20 @@ #define MBADDR_SCLDSP 0xE200 // Hardware scroll, a read to each location adds 8 to the start of the video access address therefore creating hardware scroll. 00 - reset to power up #define MBADDR_SCLBASE 0xE2 // High byte scroll base. #define MBADDR_DSPCTL 0xDFFF // Display 40/80 select register (bit 7) +#define IO_ADDR_E0 0xE0 +#define IO_ADDR_E1 0xE1 +#define IO_ADDR_E2 0xE2 +#define IO_ADDR_E3 0xE3 +#define IO_ADDR_E4 0xE4 +#define IO_ADDR_E5 0xE5 +#define IO_ADDR_E6 0xE6 +#define IO_ADDR_E7 0xE7 +#define IO_ADDR_E8 0xE8 +#define IO_PSG_BOTH 0xE9 +#define IO_ADDR_EA 0xEA +#define IO_ADDR_EB 0xEB +#define IO_PCG_PRIO 0xF0 +#define IO_PALETTE 0xF1 // Sharp MZ-2000 constants. #define MBADDR_FDC 0x0D8 // MB8866 IO Region 0D8h - 0DBh @@ -332,7 +360,7 @@ display.hwVideoMode = (display.hwVideoMode & 0x3F);\ WRITE_HARDWARE_IO(0, MBADDR_PIOA, display.hwVideoMode);\ } - #define WRITE_VRAM_CHAR(__addr__,__data__) WRITE_HARDWARE(0,__addr__,__data__) + #define WRITE_VRAM_CHAR(__addr__,__data__,__xlat__) WRITE_HARDWARE(0,__addr__,__data__) #define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) {} #define WRITE_KEYB_STROBE(__data__)\ {\ @@ -344,9 +372,9 @@ #else #define ENABLE_VIDEO() {} #define DISABLE_VIDEO() {} - #define WRITE_VRAM_CHAR(__addr__,__data__) WRITE_HARDWARE(0,__addr__,dispCodeMap[__data__].dispCode) - #define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) WRITE_HARDWARE(0,__addr__,__data__) - #define WRITE_KEYB_STROBE(__data__) WRITE_HARDWARE(0, MBADDR_KEYPA, __data__) + #define WRITE_VRAM_CHAR(__addr__,__data__,__xlat__) WRITE_HARDWARE(0,__addr__,(__xlat__ == 1 ? dispCodeMap[(int)__data__].dispCode : __data__)) + #define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) WRITE_HARDWARE(0,__addr__,__data__) + #define WRITE_KEYB_STROBE(__data__) WRITE_HARDWARE(0, MBADDR_KEYPA, __data__) #define READ_KEYB_INIT() READ_HARDWARE_INIT(0, MBADDR_KEYPB) #define READ_KEYB() READ_HARDWARE() #endif diff --git a/software/FusionX/src/z80drv/Makefile b/software/FusionX/src/z80drv/Makefile index 271061c08..75b3ea1d2 100644 --- a/software/FusionX/src/z80drv/Makefile +++ b/software/FusionX/src/z80drv/Makefile @@ -1,4 +1,5 @@ #MODEL := MZ2000 +#MODEL := MZ1500 #MODEL := MZ700 #MODEL := MZ80A #MODEL := PCW8XXX @@ -23,6 +24,7 @@ all: MZ80A: MODEL_MZ80A MZ700: MODEL_MZ700 +MZ1500: MODEL_MZ1500 MZ2000: MODEL_MZ2000 PCW8XXX: MODEL_PCW8XXX PCW9XXX: MODEL_PCW9XXX @@ -31,6 +33,8 @@ MODEL_MZ80A: $(MAKE) MODEL=MZ80A BUILD_MZ80A MODEL_MZ700: $(MAKE) MODEL=MZ700 BUILD_MZ700 +MODEL_MZ1500: + $(MAKE) MODEL=MZ1500 BUILD_MZ1500 MODEL_MZ2000: $(MAKE) MODEL=MZ2000 BUILD_MZ2000 MODEL_PCW8XXX: @@ -40,6 +44,7 @@ MODEL_PCW9XXX: BUILD_MZ80A: sharpbiter k64fcpu kmod z80ctrl BUILD_MZ700: sharpbiter k64fcpu kmod z80ctrl +BUILD_MZ1500: sharpbiter k64fcpu kmod z80ctrl BUILD_MZ2000: sharpbiter k64fcpu kmod z80ctrl BUILD_PCW8XXX: kmod z80ctrl BUILD_PCW9XXX: kmod z80ctrl diff --git a/software/FusionX/src/z80drv/src/k64fcpu.c b/software/FusionX/src/z80drv/src/k64fcpu.c index 59a1f158d..6731f047d 100644 --- a/software/FusionX/src/z80drv/src/k64fcpu.c +++ b/software/FusionX/src/z80drv/src/k64fcpu.c @@ -20,6 +20,7 @@ // out all low level control methods. // v1.01 - Updates to make compatible with the TZFS changes. // Apr v1.02 - Updates to add MZ-2000 servicing. +// May v1.03 - Updates to add MZ-1500 servicing. // // Notes: See Makefile to enable/disable conditional components // @@ -2329,6 +2330,13 @@ void loadTranZPUterDefaultROMS(uint8_t cpuConfig) } break; + case HW_MZ1500: + #if(DEBUG_ENABLED & 0x2) + if(Z80Ctrl->debug >= 2) printf("Loading 1Z_009B\n"); + #endif + result = loadTZFS(MZ_ROM_1Z_009B_40C, MZ_MROM_ADDR); + break; + case HW_MZ80B: //result = loadBIOS(MZ_ROM_MZ80B_IPL, MZ80B, MZ_MROM_ADDR); result = loadBIOS(MZ_ROM_MZ80B_IPL, MZ_MROM_ADDR); @@ -2946,6 +2954,8 @@ int main(int argc, char *argv[]) z80Control.hostType = HW_MZ80A; #elif (TARGET_HOST_MZ700 == 1) z80Control.hostType = HW_MZ700; + #elif (TARGET_HOST_MZ1500 == 1) + z80Control.hostType = HW_MZ1500; #elif (TARGET_HOST_MZ2000 == 1) z80Control.hostType = HW_MZ2000; #else diff --git a/software/FusionX/src/z80drv/src/sharpbiter.c b/software/FusionX/src/z80drv/src/sharpbiter.c index 1b48281e1..5c5aa546d 100644 --- a/software/FusionX/src/z80drv/src/sharpbiter.c +++ b/software/FusionX/src/z80drv/src/sharpbiter.c @@ -21,6 +21,7 @@ // // History: Feb 2023 v1.0 - Initial write. // Apr 2023 v1.1 - Updates to include MZ-2000. +// Apr 2023 v1.2 - Updates to include MZ-1500. // // Notes: See Makefile to enable/disable conditional components // @@ -338,12 +339,15 @@ int main(int argc, char *argv[]) #if(TARGET_HOST_MZ80A == 1) ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); - #elif(TARGET_HOST_MZ2000 == 1) - ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; - ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); #elif(TARGET_HOST_MZ700 == 1) ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); + #elif(TARGET_HOST_MZ1500 == 1) + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500; + ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); + #elif(TARGET_HOST_MZ2000 == 1) + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; + ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); #endif ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); @@ -356,10 +360,12 @@ int main(int argc, char *argv[]) ioctlCmd.cmd = IOCTL_CMD_ADD_DEVICE; #if(TARGET_HOST_MZ80A == 1) ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A; - #elif(TARGET_HOST_MZ2000 == 1) - ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; #elif(TARGET_HOST_MZ700 == 1) ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700; + #elif(TARGET_HOST_MZ1500 == 1) + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500; + #elif(TARGET_HOST_MZ2000 == 1) + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; #endif ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); @@ -382,12 +388,15 @@ int main(int argc, char *argv[]) #if(TARGET_HOST_MZ80A == 1) ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); - #elif(TARGET_HOST_MZ2000 == 1) - ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; - ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); #elif(TARGET_HOST_MZ700 == 1) ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); + #elif(TARGET_HOST_MZ1500 == 1) + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500; + ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); + #elif(TARGET_HOST_MZ2000 == 1) + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; + ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); #endif ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); @@ -419,12 +428,15 @@ int main(int argc, char *argv[]) #if(TARGET_HOST_MZ80A == 1) ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); - #elif(TARGET_HOST_MZ2000 == 1) - ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; - ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); #elif(TARGET_HOST_MZ700 == 1) ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); + #elif(TARGET_HOST_MZ1500 == 1) + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500; + ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); + #elif(TARGET_HOST_MZ2000 == 1) + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; + ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); #endif ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); @@ -450,12 +462,15 @@ int main(int argc, char *argv[]) #if(TARGET_HOST_MZ80A == 1) ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); - #elif(TARGET_HOST_MZ2000 == 1) - ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; - ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); #elif(TARGET_HOST_MZ700 == 1) ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); + #elif(TARGET_HOST_MZ1500 == 1) + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500; + ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); + #elif(TARGET_HOST_MZ2000 == 1) + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; + ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); #endif ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80; ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd); diff --git a/software/FusionX/src/z80drv/src/tzpu.h b/software/FusionX/src/z80drv/src/tzpu.h index 88bb8381c..5abcbb04c 100755 --- a/software/FusionX/src/z80drv/src/tzpu.h +++ b/software/FusionX/src/z80drv/src/tzpu.h @@ -50,6 +50,8 @@ #define OS_BASE_DIR "/apps/FusionX/host/MZ-80A/" // Linux base directory where all the files are stored. On a real tranZPUter this would be the SD card root dir. #elif (TARGET_HOST_MZ700 == 1) #define OS_BASE_DIR "/apps/FusionX/host/MZ-700/" +#elif (TARGET_HOST_MZ1500 == 1) + #define OS_BASE_DIR "/apps/FusionX/host/MZ-1500/" #elif (TARGET_HOST_MZ2000 == 1) #define OS_BASE_DIR "/apps/FusionX/host/MZ-2000/" #endif @@ -203,7 +205,7 @@ // CPLD Configuration constants. #define HWMODE_MZ80K 0x00 // Hardware mode = MZ80K #define HWMODE_MZ80C 0x01 // Hardware mode = MZ80C -#define HWMODE_MZ1200 0x02 // Hardware mode = MZ1200 +#define HWMODE_MZ1500 0x02 // Hardware mode = MZ1500 #define HWMODE_MZ80A 0x03 // Hardware mode = MZ80A #define HWMODE_MZ700 0x04 // Hardware mode = MZ700 #define HWMODE_MZ800 0x05 // Hardware mode = MZ800 @@ -421,6 +423,7 @@ #define MZ_ROM_1Z_013A_KM_40C "1Z-013A-KM.rom" // Original 40 character Monitor ROM for the Sharp MZ700 with keyboard remapped for the MZ80A. #define MZ_ROM_1Z_013A_KM_80C "1Z-013A-KM-8.rom" // Original Monitor ROM patched for the Sharp MZ700 with keyboard remapped for the MZ80A and patched for 80 column mode. #define MZ_ROM_1Z_013A_2000 "1Z-013A-2000.rom" // Original 40 character Monitor ROM for the Sharp MZ700 modified to run on an MZ-2000. +#define MZ_ROM_1Z_009B_40C "1Z-009B.rom" // Original 40 character MZ-1500 Monitor ROM. #define MZ_ROM_9Z_504M_COMBINED "MZ800_IPL.rom" // Original MZ-800 BIOS which comprises the 1Z_013B BIOS, 9Z_504M IPL, CGROM and IOCS. #define MZ_ROM_9Z_504M "MZ800_9Z_504M.rom" // Modified MZ-800 9Z_504M IPL to contain a select TZFS option. #define MZ_ROM_1Z_013B "MZ800_1Z_013B.rom" // Original MZ-800 1Z_013B MZ-700 compatible BIOS. @@ -481,7 +484,7 @@ enum TARGETS { enum MACHINE_HW_TYPES { HW_MZ80K = HWMODE_MZ80K, // Host hardware = MZ-80K. HW_MZ80C = HWMODE_MZ80C, // Host hardware = MZ-80C. - HW_MZ1200 = HWMODE_MZ1200, // Host hardware = MZ-1200. + HW_MZ1500 = HWMODE_MZ1500, // Host hardware = MZ-1500. HW_MZ80A = HWMODE_MZ80A, // Host hardware = MZ-80A. HW_MZ700 = HWMODE_MZ700, // Host hardware = MZ-700. HW_MZ800 = HWMODE_MZ800, // Host hardware = MZ-800. diff --git a/software/FusionX/src/z80drv/src/z80ctrl.c b/software/FusionX/src/z80drv/src/z80ctrl.c index 648869834..16097f023 100644 --- a/software/FusionX/src/z80drv/src/z80ctrl.c +++ b/software/FusionX/src/z80drv/src/z80ctrl.c @@ -17,6 +17,7 @@ // // History: Oct 2022 v1.0 - v1.Initial write of the z80 kernel driver software. // Feb 2023 v1.1 - Extended to allow Rom upload for RFS and other drivers. +// May 2023 v1.2 - Extended to accommodate MZ-1500 host. // // Notes: See Makefile to enable/disable conditional components // @@ -54,7 +55,7 @@ #include #include "z80driver.h" -#define VERSION "1.1" +#define VERSION "1.2" #define AUTHOR "P.D.Smart" #define COPYRIGHT "(c) 2018-23" @@ -436,7 +437,7 @@ int z80load(int fdZ80, char *fileName, uint32_t memLoadAddr, long fileOffset, lo } else { - #if(TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ80A) + #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) if(mzfHeader.loadAddr > 0x1000) { #endif @@ -446,7 +447,7 @@ int z80load(int fdZ80, char *fileName, uint32_t memLoadAddr, long fileOffset, lo // Now read in the data. fread(&Z80RAM[mzfHeader.loadAddr], mzfHeader.fileSize, 1, ptr); printf("Loaded %s, Size:%04x, Addr:%04x, Exec:%04x\n", fileName, mzfHeader.fileSize, mzfHeader.loadAddr, mzfHeader.execAddr); - #if(TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ80A) + #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) } #endif @@ -459,7 +460,7 @@ int z80load(int fdZ80, char *fileName, uint32_t memLoadAddr, long fileOffset, lo // Set PC to 2 (NST) which switches to RUN mode and executes at 0000H ioctlCmd.z80.pc = 2; #endif - #if(TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ80A) + #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) // MZ-700 or MZ-80A just use the MZF header exec address. ioctlCmd.z80.pc = mzfHeader.execAddr; #endif @@ -601,6 +602,10 @@ int ctrlCmd(int fdZ80, enum CTRL_COMMANDS cmd, long param1, long param2, long pa { ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700; } + else if(strcasecmp((char *)param1, "MZ1500") == 0) + { + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500; + } else if(strcasecmp((char *)param1, "MZ2000") == 0) { ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; @@ -638,6 +643,10 @@ int ctrlCmd(int fdZ80, enum CTRL_COMMANDS cmd, long param1, long param2, long pa { ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700; } + else if(strcasecmp((char *)param1, "MZ1500") == 0) + { + ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500; + } else if(strcasecmp((char *)param1, "MZ2000") == 0) { ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000; diff --git a/software/FusionX/src/z80drv/src/z80driver.c b/software/FusionX/src/z80drv/src/z80driver.c index 66de9d08c..ce8245a05 100644 --- a/software/FusionX/src/z80drv/src/z80driver.c +++ b/software/FusionX/src/z80drv/src/z80driver.c @@ -39,6 +39,7 @@ // if same as the target machine. This then allows the z80 driver to be // a vanilla Z80 or customisations for hosts pulled in. // Apr 2023 - v1.4.1 Completed MZ2000 mode to work with arbiter and ttymz. +// May 2023 - v1.5 Added MZ1500 modes. // // // Notes: See Makefile to enable/disable conditional components @@ -118,12 +119,15 @@ static DEFINE_MUTEX(Z80DRV_MUTEX); #if(TARGET_HOST_MZ80A == 1) #include "z80vhw_mz80a.c" #endif -#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) +#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) #include "z80vhw_rfs.c" #endif #if(TARGET_HOST_MZ700 == 1) #include "z80vhw_mz700.c" #endif +#if(TARGET_HOST_MZ1500 == 1) + #include "z80vhw_mz1500.c" +#endif #if(TARGET_HOST_MZ2000 == 1) #include "z80vhw_mz2000.c" #endif @@ -162,13 +166,19 @@ static inline void decodeMemoryMapSetup(zuint16 address, zuint8 data, uint8_t io mz700DecodeMemoryMapSetup(address, data, ioFlag, readFlag); } else #endif + #if(TARGET_HOST_MZ1500 == 1) + if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500) + { + mz1500DecodeMemoryMapSetup(address, data, ioFlag, readFlag); + } else + #endif #if(TARGET_HOST_MZ2000 == 1) if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000) { mz2000DecodeMemoryMapSetup(address, data, ioFlag, readFlag); } else #endif - #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS) { rfsDecodeMemoryMapSetup(address, data, ioFlag, readFlag); @@ -214,6 +224,12 @@ static inline zuint8 readVirtual(zuint16 address, uint8_t ioFlag) data = mz700Read(address, ioFlag); } else #endif + #if(TARGET_HOST_MZ1500 == 1) + if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500) + { + data = mz1500Read(address, ioFlag); + } else + #endif #if(TARGET_HOST_MZ2000 == 1) if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000) { @@ -227,7 +243,7 @@ static inline zuint8 readVirtual(zuint16 address, uint8_t ioFlag) } else #endif - #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) // RFS only has memory mapped registers. if((Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS) && ioFlag == 0) { @@ -268,6 +284,12 @@ static inline void writeVirtual(zuint16 address, zuint8 data, uint8_t ioFlag) mz700Write(address, data, ioFlag); } else #endif + #if(TARGET_HOST_MZ1500 == 1) + if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500) + { + mz1500Write(address, data, ioFlag); + } else + #endif #if(TARGET_HOST_MZ2000 == 1) if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000) { @@ -281,7 +303,7 @@ static inline void writeVirtual(zuint16 address, zuint8 data, uint8_t ioFlag) } else #endif - #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) // RFS only has memory mapped registers. if((Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS) && ioFlag == 0) { @@ -458,6 +480,10 @@ static zuint8 z80_read(void *context, zuint16 address) // Only read if the address is in physical RAM. #if(TARGET_HOST_PCW == 0) if(isPhysical(address)) + #elif(TARGET_HOST_MZ1500 == 1) + // MZ-1500 take into account PCG being active, always go to hardware when active. Cannot use the map because + // this can change during PCG active mode and must be reflected when PCG is deactivated. + if(isPhysicalHW(address) || (Z80Ctrl->pcgMode == 1 && address >= 0xD000)) #else if(isPhysicalHW(address)) #endif @@ -527,6 +553,26 @@ static zuint8 z80_read(void *context, zuint16 address) Z80Ctrl->keyportTrigger = 0; } } + #elif (TARGET_HOST_MZ1500 == 1) + // Keyport data? Store. + if(isHW(address) && address == 0xE001 && (Z80Ctrl->keyportStrobe & 0x0f) == 8) + { + Z80Ctrl->keyportShiftCtrl = (data & 0x40) == 0 ? 0x01 : 0x00; + } else + if(isHW(address) && address == 0xE001 && Z80Ctrl->keyportShiftCtrl == 1) + { + if((Z80Ctrl->keyportStrobe & 0x0f) == 5 && (data & 0xF0) != 0xF0) + { + Z80Ctrl->keyportHotKey = (data & 0x80) == 0 ? HOTKEY_ORIGINAL : + (data & 0x40) == 0 ? HOTKEY_RFS40 : + (data & 0x20) == 0 ? HOTKEY_TZFS : + (data & 0x10) == 0 ? HOTKEY_LINUX : 0x00; + Z80Ctrl->keyportTrigger = Z80Ctrl->keyportHotKey; + } else + { + Z80Ctrl->keyportTrigger = 0; + } + } #elif (TARGET_HOST_MZ2000 == 1) #endif @@ -548,7 +594,7 @@ static void z80_write(void *context, zuint16 address, zuint8 data) // Locals. Z_UNUSED(context) - #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) // To detect Hotkey presses, we need to store the keyboard strobe data and on keydata read. if(isHW(address) && address == 0xE000) { @@ -563,8 +609,15 @@ static void z80_write(void *context, zuint16 address, zuint8 data) if(isPhysicalRAM(address)) writeVirtualRAM(address, data); Z80Ctrl->ioReadAhead = 0; - } - else if(isPhysical(address)) + } else + + #if(TARGET_HOST_MZ1500 == 1) + // MZ-1500 take into account PCG being active, always go to hardware when active. Cannot use the map because + // this can change during PCG active mode and must be reflected when PCG is deactivated. + if(isPhysical(address) || (Z80Ctrl->pcgMode == 1 && address >= 0xD000)) + #else + if(isPhysical(address)) + #endif { // Commence cycle to write the data to real RAM. SPI_SEND_32(address, data << 8 | CPLD_CMD_WRITE_ADDR); @@ -1057,7 +1110,7 @@ int thread_z80(void * thread_nr) if(Z80RunMode == Z80_RUNNING) canRun=1; else canRun=0; mutex_unlock(&Z80RunModeMutex); - #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ2000 == 1) + #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1 || TARGET_HOST_MZ2000 == 1) // Hotkey pressed? Bring up user menu. if(Z80Ctrl->keyportTrigger != 0x00 && Z80Ctrl->keyportTriggerLast == 0) { @@ -1411,13 +1464,18 @@ void setupMemory(enum Z80_MEMORY_PROFILE mode) mz700SetupMemory(mode); else #endif + #if(TARGET_HOST_MZ1500 == 1) + if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500) + mz1500SetupMemory(mode); + else + #endif #if(TARGET_HOST_MZ2000 == 1) if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000) mz2000SetupMemory(mode); else #endif - // RFS board only works in an MZ-80A at present. - #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + // RFS board only works on an MZ-80A/MZ-700/MZ-1500 at present. + #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500) if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS) rfsSetupMemory(mode); else @@ -1442,6 +1500,11 @@ void setupMemory(enum Z80_MEMORY_PROFILE mode) // Inhibit mode disabled. Z80Ctrl->inhibitMode = 0; + + #if defined(TARGET_HOST_MZ1500) + // Flag to indicate PCG active, all memory accesses from D000:FFFF are sent to hardware. + Z80Ctrl->pcgMode = 0; + #endif return; } @@ -1675,10 +1738,10 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg) if(idx < Z80Ctrl->virtualDeviceCnt) break; - #if(TARGET_HOST_MZ80A == 0 && TARGET_HOST_MZ700 == 0) + #if(TARGET_HOST_MZ80A == 0 && TARGET_HOST_MZ700 == 0 && TARGET_HOST_MZ1500 == 0) if(ioctlCmd.vdev.device & VIRTUAL_DEVICE_RFS) { - pr_info("RFS Board currently supported on MZ-80A/MZ-700 Hosts only.\n"); + pr_info("RFS Board currently supported on MZ-80A/MZ-700/MZ-1500 Hosts only.\n"); break; } #endif @@ -1700,7 +1763,7 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg) break; #endif - #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) case VIRTUAL_DEVICE_RFS40: case VIRTUAL_DEVICE_RFS80: Z80Ctrl->virtualDevice[Z80Ctrl->virtualDeviceCnt++] = ioctlCmd.vdev.device; @@ -1717,6 +1780,14 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg) break; #endif + #if(TARGET_HOST_MZ1500 == 1) + case VIRTUAL_DEVICE_MZ1500: + Z80Ctrl->virtualDevice[Z80Ctrl->virtualDeviceCnt++] = ioctlCmd.vdev.device; + Z80Ctrl->virtualDeviceBitMap |= ioctlCmd.vdev.device; + mz1500Init(0); + break; + #endif + #if(TARGET_HOST_MZ2000 == 1) case VIRTUAL_DEVICE_MZ2000: Z80Ctrl->virtualDevice[Z80Ctrl->virtualDeviceCnt++] = ioctlCmd.vdev.device; @@ -1791,7 +1862,7 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg) break; #endif - #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) case VIRTUAL_DEVICE_RFS40: case VIRTUAL_DEVICE_RFS80: Z80Ctrl->virtualDeviceBitMap &= ~ioctlCmd.vdev.device; @@ -1806,6 +1877,13 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg) break; #endif + #if(TARGET_HOST_MZ1500 == 1) + case VIRTUAL_DEVICE_MZ1500: + Z80Ctrl->virtualDeviceBitMap &= ~ioctlCmd.vdev.device; + mz1500Remove(); + break; + #endif + #if(TARGET_HOST_MZ2000 == 1) case VIRTUAL_DEVICE_MZ2000: Z80Ctrl->virtualDeviceBitMap &= ~ioctlCmd.vdev.device; @@ -2067,7 +2145,7 @@ static int __init ModuleInit(void) Z80Ctrl->ioReadAhead = 0; Z80Ctrl->ioWriteAhead = 0; - #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) + #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1 || TARGET_HOST_MZ2000 == 1) // Initialse hotkey detection variables. Z80Ctrl->keyportStrobe = 0x00; Z80Ctrl->keyportShiftCtrl = 0x00; diff --git a/software/FusionX/src/z80drv/src/z80driver.h b/software/FusionX/src/z80drv/src/z80driver.h index e1110d370..0051fdf42 100644 --- a/software/FusionX/src/z80drv/src/z80driver.h +++ b/software/FusionX/src/z80drv/src/z80driver.h @@ -16,6 +16,7 @@ // Jan 2023 - v1.1 Added MZ-2000/MZ-80A modes. // Feb 2023 - v1.2 Added RFS virtual driver. // Apr 2023 - v1.4.1 Completed MZ2000 mode to work with arbiter and ttymz. +// May 2023 - v1.5 Added MZ1500 modes. // // Notes: See Makefile to enable/disable conditional components // @@ -40,26 +41,37 @@ #if defined(TARGET_HOST_MZ700) #define TARGET_HOST_MZ700 1 #define TARGET_HOST_MZ2000 0 + #define TARGET_HOST_MZ1500 0 #define TARGET_HOST_MZ80A 0 #define TARGET_HOST_PCW 0 #elif defined(TARGET_HOST_MZ2000) #define TARGET_HOST_MZ2000 1 + #define TARGET_HOST_MZ1500 0 + #define TARGET_HOST_MZ700 0 + #define TARGET_HOST_MZ80A 0 + #define TARGET_HOST_PCW 0 +#elif defined(TARGET_HOST_MZ1500) + #define TARGET_HOST_MZ2000 0 + #define TARGET_HOST_MZ1500 1 #define TARGET_HOST_MZ700 0 #define TARGET_HOST_MZ80A 0 #define TARGET_HOST_PCW 0 #elif defined(TARGET_HOST_MZ80A) #define TARGET_HOST_MZ80A 1 #define TARGET_HOST_MZ2000 0 + #define TARGET_HOST_MZ1500 0 #define TARGET_HOST_MZ700 0 #define TARGET_HOST_PCW 0 #elif defined(TARGET_HOST_PCW8XXX) || defined(TARGET_HOST_PCW9XXX) #define TARGET_HOST_PCW 1 #define TARGET_HOST_MZ2000 0 + #define TARGET_HOST_MZ1500 0 #define TARGET_HOST_MZ700 0 #define TARGET_HOST_MZ80A 0 #else #define TARGET_HOST_MZ700 0 // Target compilation for an MZ700 #define TARGET_HOST_MZ2000 0 // MZ2000 + #define TARGET_HOST_MZ1500 0 // MZ1500 #define TARGET_HOST_MZ80A 0 // MZ80A #define TARGET_HOST_PCW 0 // Amstrad PCW8XXX/9XXX #endif @@ -68,8 +80,8 @@ #define DRIVER_LICENSE "GPL" #define DRIVER_AUTHOR "Philip D Smart" #define DRIVER_DESCRIPTION "Z80 CPU Emulator and Hardware Interface Driver" -#define DRIVER_VERSION "v1.4.1" -#define DRIVER_VERSION_DATE "Apr 2023" +#define DRIVER_VERSION "v1.5" +#define DRIVER_VERSION_DATE "May 2023" #define DRIVER_COPYRIGHT "(C) 2018-2023" #define Z80_VIRTUAL_ROM_SIZE (65536 * 32) // Sized to maximum Kernel contiguous allocation size, 2M which is 4x512K ROMS. #define Z80_VIRTUAL_RAM_SIZE (65536 * 32) // Sized to maximum Kernel contiguous allocation size, 2M. @@ -173,6 +185,82 @@ #define INSTRUCTION_EQUIV_FREQ_448MHZ 448000000 #define INSTRUCTION_GOVERNOR_IO_SKIP 10 +enum Z80_INSTRUCTION_DELAY { + ROM_DELAY_NORMAL = INSTRUCTION_DELAY_ROM_3_54MHZ, + ROM_DELAY_X2 = INSTRUCTION_DELAY_ROM_7MHZ, + ROM_DELAY_X4 = INSTRUCTION_DELAY_ROM_14MHZ, + ROM_DELAY_X8 = INSTRUCTION_DELAY_ROM_28MHZ, + ROM_DELAY_X16 = INSTRUCTION_DELAY_ROM_56MHZ, + ROM_DELAY_X32 = INSTRUCTION_DELAY_ROM_112MHZ, + ROM_DELAY_X64 = INSTRUCTION_DELAY_ROM_224MHZ, + ROM_DELAY_X128 = INSTRUCTION_DELAY_ROM_448MHZ, + RAM_DELAY_NORMAL = INSTRUCTION_DELAY_RAM_3_54MHZ, + RAM_DELAY_X2 = INSTRUCTION_DELAY_RAM_7MHZ, + RAM_DELAY_X4 = INSTRUCTION_DELAY_RAM_14MHZ, + RAM_DELAY_X8 = INSTRUCTION_DELAY_RAM_28MHZ, + RAM_DELAY_X16 = INSTRUCTION_DELAY_RAM_56MHZ, + RAM_DELAY_X32 = INSTRUCTION_DELAY_RAM_112MHZ, + RAM_DELAY_X64 = INSTRUCTION_DELAY_RAM_224MHZ, + RAM_DELAY_X128 = INSTRUCTION_DELAY_RAM_448MHZ, + CPU_FREQUENCY_NORMAL = INSTRUCTION_EQUIV_FREQ_3_54MHZ, + CPU_FREQUENCY_X2 = INSTRUCTION_EQUIV_FREQ_7MHZ, + CPU_FREQUENCY_X4 = INSTRUCTION_EQUIV_FREQ_14MHZ, + CPU_FREQUENCY_X8 = INSTRUCTION_EQUIV_FREQ_28MHZ, + CPU_FREQUENCY_X16 = INSTRUCTION_EQUIV_FREQ_56MHZ, + CPU_FREQUENCY_X32 = INSTRUCTION_EQUIV_FREQ_112MHZ, + CPU_FREQUENCY_X64 = INSTRUCTION_EQUIV_FREQ_224MHZ, + CPU_FREQUENCY_X128 = INSTRUCTION_EQUIV_FREQ_448MHZ, +}; +#endif +// +// MZ-1500 +#if(TARGET_HOST_MZ1500 == 1) +#if(DEBUG_ENABLED > 0) + #define INSTRUCTION_DELAY_ROM_3_54MHZ 253 + #define INSTRUCTION_DELAY_ROM_7MHZ 126 + #define INSTRUCTION_DELAY_ROM_14MHZ 63 + #define INSTRUCTION_DELAY_ROM_28MHZ 32 + #define INSTRUCTION_DELAY_ROM_56MHZ 16 + #define INSTRUCTION_DELAY_ROM_112MHZ 8 + #define INSTRUCTION_DELAY_ROM_224MHZ 4 + #define INSTRUCTION_DELAY_ROM_448MHZ 1 + #define INSTRUCTION_DELAY_RAM_3_54MHZ 253 + #define INSTRUCTION_DELAY_RAM_7MHZ 126 + #define INSTRUCTION_DELAY_RAM_14MHZ 63 + #define INSTRUCTION_DELAY_RAM_28MHZ 32 + #define INSTRUCTION_DELAY_RAM_56MHZ 16 + #define INSTRUCTION_DELAY_RAM_112MHZ 8 + #define INSTRUCTION_DELAY_RAM_224MHZ 4 + #define INSTRUCTION_DELAY_RAM_448MHZ 1 +#endif +#if(DEBUG_ENABLED == 0) + #define INSTRUCTION_DELAY_ROM_3_54MHZ 253 + #define INSTRUCTION_DELAY_ROM_7MHZ 126 + #define INSTRUCTION_DELAY_ROM_14MHZ 63 + #define INSTRUCTION_DELAY_ROM_28MHZ 32 + #define INSTRUCTION_DELAY_ROM_56MHZ 16 + #define INSTRUCTION_DELAY_ROM_112MHZ 8 + #define INSTRUCTION_DELAY_ROM_224MHZ 4 + #define INSTRUCTION_DELAY_ROM_448MHZ 1 + #define INSTRUCTION_DELAY_RAM_3_54MHZ 253 + #define INSTRUCTION_DELAY_RAM_7MHZ 126 + #define INSTRUCTION_DELAY_RAM_14MHZ 63 + #define INSTRUCTION_DELAY_RAM_28MHZ 32 + #define INSTRUCTION_DELAY_RAM_56MHZ 16 + #define INSTRUCTION_DELAY_RAM_112MHZ 8 + #define INSTRUCTION_DELAY_RAM_224MHZ 4 + #define INSTRUCTION_DELAY_RAM_448MHZ 1 +#endif +#define INSTRUCTION_EQUIV_FREQ_3_54MHZ 3540000 +#define INSTRUCTION_EQUIV_FREQ_7MHZ 7000000 +#define INSTRUCTION_EQUIV_FREQ_14MHZ 14000000 +#define INSTRUCTION_EQUIV_FREQ_28MHZ 28000000 +#define INSTRUCTION_EQUIV_FREQ_56MHZ 56000000 +#define INSTRUCTION_EQUIV_FREQ_112MHZ 112000000 +#define INSTRUCTION_EQUIV_FREQ_224MHZ 224000000 +#define INSTRUCTION_EQUIV_FREQ_448MHZ 448000000 +#define INSTRUCTION_GOVERNOR_IO_SKIP 10 + enum Z80_INSTRUCTION_DELAY { ROM_DELAY_NORMAL = INSTRUCTION_DELAY_ROM_3_54MHZ, ROM_DELAY_X2 = INSTRUCTION_DELAY_ROM_7MHZ, @@ -612,8 +700,9 @@ enum VIRTUAL_DEVICE { VIRTUAL_DEVICE_NONE = 0x00000000, VIRTUAL_DEVICE_MZ80A = 0x00000001, VIRTUAL_DEVICE_MZ700 = 0x00000002, - VIRTUAL_DEVICE_MZ2000 = 0x00000004, - VIRTUAL_DEVICE_PCW = 0x00000008, + VIRTUAL_DEVICE_MZ1500 = 0x00000004, + VIRTUAL_DEVICE_MZ2000 = 0x00000008, + VIRTUAL_DEVICE_PCW = 0x00000010, VIRTUAL_DEVICE_RFS40 = 0x01000000, VIRTUAL_DEVICE_RFS80 = 0x02000000, VIRTUAL_DEVICE_RFS = 0x03000000, @@ -674,6 +763,11 @@ typedef struct { // blocks actions which arent allowed during inhibit. uint8_t inhibitMode; + #if defined(TARGET_HOST_MZ1500) + // Flag to indicate PCG active, all memory accesses from D000:FFFF are sent to hardware. + uint8_t pcgMode; + #endif + // I/O lookahead flags - to overcome SSD202 io slowness. uint8_t ioReadAhead; uint8_t ioWriteAhead; diff --git a/software/FusionX/src/z80drv/src/z80vhw_mz1500.c b/software/FusionX/src/z80drv/src/z80vhw_mz1500.c new file mode 100644 index 000000000..304764e47 --- /dev/null +++ b/software/FusionX/src/z80drv/src/z80vhw_mz1500.c @@ -0,0 +1,458 @@ +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Name: z80vhw_mz1500.c +// Created: May 2023 +// Author(s): Philip Smart +// Description: Z80 Virtual Hardware Driver - MZ-1500 +// This file contains the methods used to emulate the original Sharp MZ-1500 without +// any additions, such as the RFS or TZFS boards. +// +// These drivers are intended to be instantiated inline to reduce overhead of a call +// and as such, they are included like header files rather than C linked object files. +// Credits: +// Copyright: (c) 2019-2023 Philip Smart +// +// History: May 2023 v1.0 - Initial write based on the MZ700 module. +// +// Notes: See Makefile to enable/disable conditional components +// +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// This source file is free software: you can redistribute it and#or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "z80io.h" + +#include +#include +#include +#include + +// Device constants. +#define RAM_BASE_ADDR 0x00000 // Base address of the 512K RAM. + +// PCW control. +typedef struct { + uint8_t regCtrl; // Control register. +} t_MZ1500Ctrl; + +// RFS Board control. +static t_MZ1500Ctrl MZ1500Ctrl; + +//------------------------------------------------------------------------------------------------------------------------------- +// +// +//------------------------------------------------------------------------------------------------------------------------------- + +// Method to setup the memory page config to reflect the PCW configuration. +void mz1500SetupMemory(enum Z80_MEMORY_PROFILE mode) +{ + // Locals. + uint32_t idx; + + // Setup defaults. + MZ1500Ctrl.regCtrl = 0x00; + + // Setup default mode according to run mode, ie. Physical run or Virtual run. + // + if(mode == USE_PHYSICAL_RAM) + { + // Initialise the page pointers and memory to use physical RAM. + for(idx=0x0000; idx < MEMORY_PAGE_SIZE; idx+=MEMORY_BLOCK_GRANULARITY) + { + if(idx >= 0 && idx < 0x1000) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_ROM, idx); + } + else if(idx >= 0x1000 && idx < 0xD000) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_RAM, idx); + } + else if(idx >= 0xD000 && idx < 0xE000) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx); + } + else if(idx >= 0xE000 && idx < 0xE800) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx); + } + else if(idx >= 0xE800 && idx < 0x10000) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_ROM, idx); + } else + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_RAM, idx); + } + } + for(idx=0x0000; idx < IO_PAGE_SIZE; idx++) + { + Z80Ctrl->iopage[idx] = idx | IO_TYPE_PHYSICAL_HW; + } + // Cancel refresh as using physical RAM for program automatically refreshes DRAM. + Z80Ctrl->refreshDRAM = 0; + } + else if(mode == USE_VIRTUAL_RAM) + { + // Initialise the page pointers and memory to use virtual RAM. + for(idx=0x0000; idx < MEMORY_PAGE_SIZE; idx+=MEMORY_BLOCK_GRANULARITY) + { + if(idx >= 0 && idx < 0x1000) + { + setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_VIRTUAL_ROM, idx); + } + else if(idx >= 0x1000 && idx < 0xD000) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx); + } + else if(idx >= 0xD000 && idx < 0xE000) + { + setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_PHYSICAL_VRAM, idx); + } + else if(idx >= 0xE000 && idx < 0xE800) + { + setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_PHYSICAL_HW, idx); + } + else if(idx >= 0xE800 && idx < 0xF000) + { + setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_VIRTUAL_ROM, idx); + } + else if(idx >= 0xF000 && idx < 0x10000) + { + setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_VIRTUAL_ROM, idx); + } + } + for(idx=0x0000; idx < IO_PAGE_SIZE; idx++) + { + Z80Ctrl->iopage[idx] = idx | IO_TYPE_PHYSICAL_HW; + } + // Enable refresh as using virtual RAM stops refresh of host DRAM. + Z80Ctrl->refreshDRAM = 2; + } + + // Reset memory paging to default. + SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR); + + pr_info("MZ-1500 Memory Setup complete.\n"); +} + +// Method to load a ROM image into the RAM memory. +// +uint8_t mz1500LoadROM(const char* romFileName, uint32_t loadAddr, uint32_t loadSize) +{ + // Locals. + uint8_t result = 0; + long noBytes; + struct file *fp; + + fp = filp_open(romFileName, O_RDONLY, 0); + if(IS_ERR(fp)) + { + pr_info("Error opening ROM Image:%s\n:", romFileName); + result = 1; + } else + { + vfs_llseek(fp, 0, SEEK_SET); + noBytes = kernel_read(fp, fp->f_pos, &Z80Ctrl->ram[loadAddr], loadSize); + if(noBytes < loadSize) + { + pr_info("Short load, ROM Image:%s, bytes loaded:%08x\n:", romFileName, loadSize); + } + filp_close(fp,NULL); + } + + return(result); +} + +// Perform any setup operations, such as variable initialisation, to enable use of this module. +void mz1500Init(uint8_t mode) +{ + // Locals. + uint32_t idx; + + // Reset memory paging to default. + SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR); + + // Initialise the virtual RAM from the HOST DRAM. This is to maintain compatibility as some applications (in my experience) have + // bugs, which Im putting down to not initialising variables. The host DRAM is in a pattern of 0x00..0x00, 0xFF..0xFF repeating + // when first powered on. + pr_info("Sync Host RAM to virtual RAM.\n"); + for(idx=0; idx < Z80_VIRTUAL_RAM_SIZE; idx++) + { + if(idx >= 0x1000 && idx < 0xD000) + { + SPI_SEND32((uint32_t)idx << 16 | CPLD_CMD_READ_ADDR); + while(CPLD_READY() == 0); + Z80Ctrl->ram[idx] = z80io_PRL_Read8(1); + } else + { + Z80Ctrl->ram[idx] = 0x00; + } + } + + // Original mode, ie. no virtual devices active, copy the host BIOS into the Virtual ROM and initialise remainder of ROM memory + // such that the host behaves as per original spec. + pr_info("Sync Host BIOS to virtual ROM.\n"); + for(idx=0; idx < Z80_VIRTUAL_ROM_SIZE; idx++) + { + // Copy BIOS and any add-on ROMS. + if((idx >= 0x0000 && idx < 0x1000) || (idx >= 0xE800 && idx < 0x10000)) + { + SPI_SEND32((uint32_t)idx << 16 | CPLD_CMD_READ_ADDR); + while(CPLD_READY() == 0); + Z80Ctrl->rom[idx] = z80io_PRL_Read8(1); + } else + { + Z80Ctrl->rom[idx] = 0x00; + } + } + + // Initial memory config. + mz1500SetupMemory(Z80Ctrl->defaultPageMode); + + pr_info("Enabling MZ-1500 driver.\n"); + return; +} + +// Perform any de-initialisation when the driver is removed. +void mz1500Remove(void) +{ + pr_info("Removing MZ-1500 driver.\n"); + return; +} + +// Method to decode an address and make any system memory map changes as required. +// +static inline void mz1500DecodeMemoryMapSetup(zuint16 address, zuint8 data, uint8_t ioFlag, uint8_t readFlag) +{ + // Locals. + uint32_t idx; + + // Decoding memory address or I/O address? + if(ioFlag == 0) + { + // #if(DEBUG_ENABLED & 1) + // if(Z80Ctrl->debug >= 2) + // { + // pr_info("MEM:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag); + // } + // #endif + // Certain machines have memory mapped I/O, these need to be handled in-situ as some reads may change the memory map. + // These updates are made whilst waiting for the CPLD to retrieve the requested byte. + // + // 0000 - 0FFF : MZ80K/A/700 = Monitor ROM or RAM (MZ80A rom swap) + // 1000 - CFFF : MZ80K/A/700 = RAM + // C000 - CFFF : MZ80A = Monitor ROM (MZ80A rom swap) + // D000 - D7FF : MZ80K/A/700 = VRAM + // D800 - DFFF : MZ1500 = Colour VRAM (MZ1500) + // E000 - E003 : MZ80K/A/700 = 8255 + // E004 - E007 : MZ80K/A/700 = 8254 + // E008 - E00B : MZ80K/A/700 = LS367 + // E00C - E00F : MZ80A = Memory Swap (MZ80A) + // E010 - E013 : MZ80A = Reset Memory Swap (MZ80A) + // E014 : MZ80A/700 = Normat CRT display + // E015 : MZ80A/700 = Reverse CRT display + // E200 - E2FF : MZ80A/700 = VRAM roll up/roll down. + // E800 - EFFF : MZ80K/A/700 = User ROM socket or DD Eprom (MZ1500) + // F000 - F7FF : MZ80K/A/700 = Floppy Disk interface. + // F800 - FFFF : MZ80K/A/700 = Floppy Disk interface. + switch(address) + { + default: + break; + } + } else + { + // #if(DEBUG_ENABLED & 1) + // if(Z80Ctrl->debug >= 2) + // { + // pr_info("IO:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag); + // } + // #endif + + // Determine if this is a memory management port and update the memory page if required. + switch(address & 0x00FF) + { + // MZ1500 memory mode switch. + // + // MZ-1500 + // |0000:0FFF|1000:CFFF|D000:FFFF + // ------------------------------ + // OUT 0xE0 = |DRAM | | + // OUT 0xE1 = | | |DRAM + // OUT 0xE2 = |MONITOR | | + // OUT 0xE3 = | | |Memory Mapped I/O + // OUT 0xE4 = |MONITOR |DRAM |Memory Mapped I/O + // OUT 0xE5 = | | |PCG Enable + // OUT 0xE6 = | | |PCG Disable + // + // = Return to the state prior to the complimentary command being invoked. + // Enable lower 4K block as DRAM + case IO_ADDR_E0: + for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx); + } + break; + + // Enable upper 12K block, including Video/Memory Mapped peripherals area, as DRAM. + case IO_ADDR_E1: + if(!Z80Ctrl->inhibitMode) + { + for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY) + { + // MZ-1500 mode we only work in first 64K block. + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx); + } + } + break; + + // Enable MOnitor ROM in lower 4K block + case IO_ADDR_E2: + for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx); + } + break; + + // Enable Video RAM and Memory mapped peripherals in upper 12K block. + case IO_ADDR_E3: + if(!Z80Ctrl->inhibitMode) + { + for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx); + } + for(idx=0xE000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx); + } + } + break; + + // Reset to power on condition memory map. + case IO_ADDR_E4: + // Lower 4K set to Monitor ROM. + for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx); + } + if(!Z80Ctrl->inhibitMode) + { + // Upper 12K to hardware. + for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx); + } + for(idx=0xE000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY) + { + setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx); + } + } + break; + + // PCG Bank Switching. + // 7 6 5 4 3 2 1 0 + // 0 0 - CGROM + // 0 1 - PCG Blue Plane + // 1 0 - PCG Red Plane + // 1 1 - PCG Green Plane + case IO_ADDR_E5: + // Any PCG access goes to hardware, set flag and access occurs in primary read/write routines. + Z80Ctrl->pcgMode = 1; + break; + + // Disable PCG Bank Switching. + case IO_ADDR_E6: + // Disable PCG mode. + Z80Ctrl->pcgMode = 0; + break; + + // Port is not a memory management port. + default: + break; + } + } +} + +// Method to read from either the memory mapped registers if enabled else the RAM. +static inline uint8_t mz1500Read(zuint16 address, uint8_t ioFlag) +{ + // Locals. + uint8_t data = 0xFF; + + // I/O Operation? + if(ioFlag) + { + switch(address) + { + default: + break; + } + } else + { + switch(address) + { + default: + if(isVirtualMemory(address)) + { + // Retrieve data from virtual memory. + data = isVirtualROM(address) ? readVirtualROM(address) : readVirtualRAM(address); + } + break; + } + } + + return(data); +} + +// Method to handle writes. +static inline void mz1500Write(zuint16 address, zuint8 data, uint8_t ioFlag) +{ + // Locals. + // uint32_t idx; + + // I/O Operation? + if(ioFlag) + { + switch(address) + { + default: + break; + } + } else + { + switch(address) + { + default: + if(isVirtualRAM(address)) + { + // Update virtual memory. + writeVirtualRAM(address, data); + } + } + } + return; +} diff --git a/software/FusionX/src/z80drv/src/z80vhw_rfs.c b/software/FusionX/src/z80drv/src/z80vhw_rfs.c index 00d93fdbf..8239e2300 100644 --- a/software/FusionX/src/z80drv/src/z80vhw_rfs.c +++ b/software/FusionX/src/z80drv/src/z80vhw_rfs.c @@ -95,6 +95,8 @@ #define ROM_DIR "/apps/FusionX/host/MZ-80A/RFS/" #elif(TARGET_HOST_MZ700 == 1) #define ROM_DIR "/apps/FusionX/host/MZ-700/RFS/" +#elif(TARGET_HOST_MZ1500 == 1) + #define ROM_DIR "/apps/FusionX/host/MZ-1500/RFS/" #else #error "Unknown host configured." #endif @@ -255,9 +257,14 @@ void rfsSetupMemory(enum Z80_MEMORY_PROFILE mode) // Enable refresh as using virtual RAM stops refresh of host DRAM. Z80Ctrl->refreshDRAM = 2; - #if (TARGET_HOST_MZ700 == 1) + #if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) // Reset memory paging to default. SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR); + + #if (TARGET_HOST_MZ1500 == 1) + // MZ-1500, E4 reset closes the PCG access. + Z80Ctrl->pcgMode = 0; + #endif #endif // No I/O Ports on the RFS board. @@ -312,9 +319,14 @@ void rfsInit(uint8_t mode80c) Z80Ctrl->rom[idx+(Z80_VIRTUAL_ROM_SIZE-0x10000)] = z80io_PRL_Read8(1); } - #if (TARGET_HOST_MZ700 == 1) + #if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1) // Reset memory paging to default. SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR); + + #if (TARGET_HOST_MZ1500 == 1) + // MZ-1500, E4 reset closes the PCG access. + Z80Ctrl->pcgMode = 0; + #endif #endif pr_info("Enabling RFS(%d) driver.\n", mode80c == 1 ? 80 : 40);