diff --git a/software/FusionX/bin/k64fcpu b/software/FusionX/bin/k64fcpu index ab6e2c48a..7a0ebca95 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 5cfccdbf7..c10c6ba1f 100755 Binary files a/software/FusionX/bin/sharpbiter and b/software/FusionX/bin/sharpbiter differ diff --git a/software/FusionX/modules/ttymzdrv.ko b/software/FusionX/modules/ttymzdrv.ko index 6bbd66c18..e164d17ed 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 623569693..4fa2aa404 100644 Binary files a/software/FusionX/modules/z80drv.ko and b/software/FusionX/modules/z80drv.ko differ diff --git a/software/FusionX/src/ttymz/sharpmz.c b/software/FusionX/src/ttymz/sharpmz.c index dbd82e2f7..6ca787940 100644 --- a/software/FusionX/src/ttymz/sharpmz.c +++ b/software/FusionX/src/ttymz/sharpmz.c @@ -82,6 +82,7 @@ extern "C" { // { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, // 0XEF // { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 } // 0XFF //}; +#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) static t_dispCodeMap dispCodeMap[] = { { 0xCC }, // NUL '\0' (null character) { 0xE0 }, // SOH (start of heading) @@ -212,6 +213,7 @@ static t_dispCodeMap dispCodeMap[] = { { 0xA5 }, // ~ { 0xC0 } // DEL }; +#endif #if (TARGET_HOST_MZ700 == 1) static t_scanCodeMap scanCodeMap[] = { @@ -1155,468 +1157,558 @@ static t_scanCodeMap scanCodeMap[] = { static t_scanCodeMap scanCodeMap[] = { // MZ_2000 NO SHIFT {{ - // S0 00 - 07 - NOKEY , // BREAK/CTRL - NOKEY , // - NOKEY , // - NOKEY , // - NOKEY , // - NOKEY , // - GRAPHKEY , // GRAPH - NOKEY , // SHIFT + // S0 00 - 07 + FUNC8 , // Function Key 8 + FUNC7 , // Function Key 7 + FUNC6 , // Function Key 6 + FUNC5 , // Function Key 5 + FUNC4 , // Function Key 4 + FUNC3 , // Function Key 3 + FUNC2 , // Function Key 2 + FUNC1 , // Function Key 1 // S1 08 - 0F - '2' , // 2 - '1' , // 1 - 'w' , // w - 'q' , // q - 'a' , // a - BACKS , // DELETE - NOKEY , // NULL - 'z' , // z + '-' , // KP - + '+' , // KP + + '.' , // KP . + DBLZERO , // KP Double Zero + '9' , // KP 9 + '8' , // KP 8 + FUNC10 , // Function Key 10 + FUNC9 , // Function Key 9 // S2 10 - 17 - '4' , // 4 - '3' , // 3 - 'r' , // r - 'e' , // e - 'd' , // d - 's' , // s - 'x' , // x - 'c' , // c + '7' , // KP 7 + '6' , // KP 6 + '5' , // KP 5 + '4' , // KP 4 + '3' , // KP 3 + '2' , // KP 2 + '1' , // KP 1 + '0' , // KP 0 // S3 18 - 1F - '6' , // 6 - '5' , // 5 - 'y' , // y - 't' , // t + BREAKKEY , // Break Key + CURSRIGHT, // Cursor Right + CURSLEFT , // Cursor Left + CURSDOWN , // Cursor Down + CURSUP , // Cursor Up + CR , // Carriage Return + SPACE , // SPACE + TAB , // TAB + // S4 20 - 27 'g' , // g 'f' , // f - 'v' , // v + 'e' , // e + 'd' , // d + 'c' , // c 'b' , // b - // S4 20 - 27 - '8' , // 8 - '7' , // 7 - 'i' , // i - 'u' , // u - 'j' , // j - 'h' , // h - 'n' , // n - ' ' , // SPACE + 'a' , // a + '/' , // / // S5 28 - 2F - '0' , // 0 - '9' , // 9 - 'p' , // p 'o' , // o + 'n' , // n + 'm' , // m 'l' , // l 'k' , // k - ',' , // , - 'm' , // m + 'j' , // j + 'i' , // i + 'h' , // h // S6 30 - 37 - '^' , // ^ - '-' , // - - '[' , // [ - '@' , // @ - ':' , // : - ';' , // ; - '/' , // / - '.' , // . + 'w' , // w + 'v' , // v + 'u' , // u + 't' , // t + 's' , // s + 'r' , // r + 'q' , // q + 'p' , // p // S7 38 - 3F - HOMEKEY , // HOME. + ',' , // , + '.' , // . + '?' , // Question '\\' , // Backslash - CURSRIGHT, // CURSOR RIGHT - CURSUP , // CURSOR UP - CR , // CR - ']' , // ] + '^' , // ^ + 'z' , // z + 'y' , // y + 'x' , // x + // S8 40 - 47 + '7' , // 7 + '6' , // 6 + '5' , // 5 + '4' , // 4 + '3' , // 3 + '2' , // 2 + '1' , // 1 + '0' , // 0 + // S9 48 - 4F NOKEY , // - '?' , // ? - // S8 40 - 47 - Keypad keys. - '8' , // Keypad 8 - '7' , // 7 - '5' , // 5 - '4' , // 4 - '2' , // 2 - '1' , // 1 - DBLZERO , // 00 - '0' , // 0 - // S9 48 - 4F - Keypad keys. - '+' , // + - '0' , // 9 - '-' , // - - '6' , // 6 + '[' , // [ + '@' , // @ + '-' , // - + ';' , // ; + ':' , // : + '9' , // 9 + '8' , // 8 + // S10 50 - 57 NOKEY , // - '3' , // 3 - NOKEY , - '.' // . + NOKEY , // + NOKEY , // + NOKEY , // + DELETE , // DELETE + HOMEKEY , // HOME + NOKEY , // + ']' , // ] + // S11 58 - 5F + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // RVS + NOKEY , // SHIFT + SHIFTLOCKKEY, // SHIFT LOCK + GRAPHKEY // GRAPH }}, // MZ_2000 CAPS LOCK {{ - // S0 00 - 07 - NOKEY , // BREAK/CTRL - NOKEY , // - NOKEY , // - NOKEY , // - NOKEY , // - NOKEY , // - ALPHAKEY , // GRAPH - NOKEY , // SHIFT + // S0 00 - 07 + FUNC7 , // Function Key 7 + FUNC6 , // Function Key 6 + FUNC5 , // Function Key 5 + FUNC4 , // Function Key 4 + FUNC3 , // Function Key 3 + FUNC2 , // Function Key 2 + FUNC1 , // Function Key 1 + FUNC8 , // Function Key 8 // S1 08 - 0F - '2' , // 2 - '1' , // 1 - 'W' , // W - 'Q' , // Q - 'A' , // A - BACKS , // DELETE - NOKEY , // NULL - 'Z' , // Z + '-' , // KP - + '+' , // KP + + '.' , // KP . + DBLZERO , // KP Double Zero + '9' , // KP 9 + '8' , // KP 8 + FUNC10 , // Function Key 10 + FUNC9 , // Function Key 9 // S2 10 - 17 - '4' , // 4 - '3' , // 3 - 'R' , // R - 'E' , // E - 'D' , // D - 'S' , // S - 'X' , // X - 'C' , // C + '7' , // KP 7 + '6' , // KP 6 + '5' , // KP 5 + '4' , // KP 4 + '3' , // KP 3 + '2' , // KP 2 + '1' , // KP 1 + '0' , // KP 0 // S3 18 - 1F - '6' , // 6 - '5' , // 5 - 'Y' , // Y - 'T' , // T + BREAKKEY , // Break Key + CURSRIGHT, // Cursor Right + CURSLEFT , // Cursor Left + CURSDOWN , // Cursor Down + CURSUP , // Cursor Up + CR , // Carriage Return + SPACE , // SPACE + TAB , // TAB + // S4 20 - 27 'G' , // G 'F' , // F - 'V' , // V + 'E' , // E + 'D' , // D + 'C' , // C 'B' , // B - // S4 20 - 27 - '8' , // 8 - '7' , // 7 - 'I' , // I - 'U' , // U - 'J' , // J - 'H' , // H - 'N' , // N - ' ' , // SPACE + 'A' , // A + '/' , // / // S5 28 - 2F - '0' , // 0 - '9' , // 9 - 'P' , // P 'O' , // O + 'N' , // N + 'M' , // M 'L' , // L 'K' , // K - ',' , // , - 'M' , // M + 'J' , // J + 'I' , // I + 'H' , // H // S6 30 - 37 - '^' , // ^ - '-' , // - - '[' , // [ - '@' , // @ - ':' , // : - ';' , // ; - '/' , // / - '.' , // . + 'W' , // W + 'V' , // V + 'U' , // U + 'T' , // T + 'S' , // S + 'R' , // R + 'Q' , // Q + 'P' , // P // S7 38 - 3F - HOMEKEY , // HOME. + ',' , // , + '.' , // . + '?' , // Question '\\' , // Backslash - CURSRIGHT, // CURSOR RIGHT - CURSUP , // CURSOR UP - CR , // CR - ']' , // ] + '^' , // ^ + 'Z' , // Z + 'Y' , // Y + 'X' , // X + // S8 40 - 47 + '7' , // 7 + '6' , // 6 + '5' , // 5 + '4' , // 4 + '3' , // 3 + '2' , // 2 + '1' , // 1 + '0' , // 0 + // S9 48 - 4F NOKEY , // - '?' , // ? - // S8 40 - 47 - Keypad keys. - '8' , // Keypad 8 - '7' , // 7 - '5' , // 5 - '4' , // 4 - '2' , // 2 - '1' , // 1 - DBLZERO , // 00 - '0' , // 0 - // S9 48 - 4F - Keypad keys. - '+' , // + - '0' , // 9 - '-' , // - - '6' , // 6 + '[' , // [ + '@' , // @ + '-' , // - + ';' , // ; + ':' , // : + '9' , // 9 + '8' , // 8 + // S10 50 - 57 NOKEY , // - '3' , // 3 - NOKEY , - '.' // . + NOKEY , // + NOKEY , // + NOKEY , // + DELETE , // DELETE + HOMEKEY , // HOME + NOKEY , // + ']' , // [ + // S11 58 - 5F + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // RVS + NOKEY , // SHIFT + SHIFTLOCKKEY, // SHIFT LOCK + GRAPHKEY // GRAPH }}, // MZ_2000 SHIFT LOCK. {{ - // S0 00 - 07 - NOKEY , // BREAK/CTRL - NOKEY , // - NOKEY , // - NOKEY , // - NOKEY , // - NOKEY , // - ALPHAKEY , // GRAPH - NOKEY , // SHIFT + // S0 00 - 07 + FUNC8 , // Function Key 8 + FUNC7 , // Function Key 7 + FUNC6 , // Function Key 6 + FUNC5 , // Function Key 5 + FUNC4 , // Function Key 4 + FUNC3 , // Function Key 3 + FUNC2 , // Function Key 2 + FUNC1 , // Function Key 1 // S1 08 - 0F - '"' , // " - '!' , // ! - 'W' , // W - 'Q' , // Q - 'A' , // A - INSERT , // INSERT - NOKEY , // NULL - 'Z' , // Z + '-' , // KP - + '+' , // KP + + '.' , // KP . + DBLZERO , // KP Double Zero + '9' , // KP 9 + '8' , // KP 8 + FUNC10 , // Function Key 10 + FUNC9 , // Function Key 9 // S2 10 - 17 - '$' , // $ - '#' , // # - 'R' , // R - 'E' , // E - 'D' , // D - 'S' , // S - 'X' , // X - 'C' , // C + '7' , // KP 7 + '6' , // KP 6 + '5' , // KP 5 + '4' , // KP 4 + '3' , // KP 3 + '2' , // KP 2 + '1' , // KP 1 + '0' , // KP 0 // S3 18 - 1F - '&' , // & - '%' , // % - 'Y' , // Y - 'T' , // T + BREAKKEY , // Break Key + NOKEY , // + NOKEY , // + PAGEDOWN , // Page Down + PAGEUP , // Page Up + CR , // Carriage Return + SPACE , // SPACE + TAB , // TAB + // S4 20 - 27 'G' , // G 'F' , // F - 'V' , // V + 'E' , // E + 'D' , // D + 'C' , // C 'B' , // B - // S4 20 - 27 - '(' , // ( - '\'' , // ' - 'I' , // I - 'U' , // U - 'J' , // J - 'H' , // H - 'N' , // N - ' ' , // SPACE + 'A' , // A + NOKEY , // Arrow Right // S5 28 - 2F - '_' , // _ - ')' , // ) - 'P' , // P 'O' , // O + 'N' , // N + 'M' , // M 'L' , // L 'K' , // K - '<' , // < - 'M' , // M + 'J' , // J + 'I' , // I + 'H' , // H // S6 30 - 37 - '~' , // ~ - '=' , // = - '{' , // { - '`' , // ` - '*' , // * - '+' , // + - NOKEY , // - '>' , // > + 'W' , // W + 'V' , // V + 'U' , // U + 'T' , // T + 'S' , // S + 'R' , // R + 'Q' , // Q + 'P' , // P // S7 38 - 3F - CLRKEY , // CLR. + '<' , // < + '>' , // > + NOKEY , // Arrow Up '|' , // | - CURSLEFT , // CURSOR LEFT - CURSDOWN , // CURSOR DOWN - CR , // CR - '}' , // } + '~' , // ~ + 'Z' , // Z + 'Y' , // Y + 'X' , // X + // S8 40 - 47 + '\'' , // ' + '&' , // & + '%' , // % + '$' , // $ + '#' , // # + '"' , // Double Quote + '!' , // ! + '-' , // - + // S9 48 - 4F + NOKEY , // + '{' , // { + '\\' , // Back slash + '=' , // = + '+' , // + + '*' , // * + ')' , // ) + '(' , // ( + // S10 50 - 57 NOKEY , // NOKEY , // - // S8 40 - 47 - Keypad keys. - '8' , // Keypad 8 - '7' , // 7 - '5' , // 5 - '4' , // 4 - '2' , // 2 - '1' , // 1 - DBLZERO , // 00 - '0' , // 0 - // S9 48 - 4F - Keypad keys. - '+' , // + - '0' , // 9 - '-' , // - - '6' , // 6 + NOKEY , // + NOKEY , // + INSERT , // INSERT + CLRKEY , // CLR + NOKEY , // + '}' , // } + // S11 58 - 5F NOKEY , // - '3' , // 3 - NOKEY , - '.' // . + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // RVS + NOKEY , // SHIFT + SHIFTLOCKKEY, // SHIFT LOCK + ALPHAKEY // ALPHA }}, // MZ_2000 CONTROL CODE {{ - // S0 00 - 07 - NOKEY , // BREAK/CTRL - NOKEY , // - NOKEY , // - NOKEY , // - NOKEY , // - NOKEY , // - ALPHAGRAPHKEY, // GRAPH - NOKEY , // SHIFT + // S0 00 - 07 + FUNC8 , // Function Key 8 + FUNC7 , // Function Key 7 + FUNC6 , // Function Key 6 + FUNC5 , // Function Key 5 + HOTKEY_LINUX, // Function Key 4 - Hotkey to invoke Linux mode. + FUNC3 , // Function Key 3 + FUNC2 , // Function Key 2 + HOTKEY_ORIGINAL, // Function Key 1 - Hotkey for Aribiter to switch to original mode. // S1 08 - 0F - NOKEY , // - NOKEY , // - CTRL_W , // CTRL_W - CTRL_Q , // CTRL_Q - CTRL_A , // CTRL_A - DELETE , // DELETE - NOKEY , // NULL - CTRL_Z , // CTRL_Z + '-' , // KP - + '+' , // KP + + '.' , // KP . + DBLZERO , // KP Double Zero + '9' , // KP 9 + '8' , // KP 8 + FUNC10 , // Function Key 10 + FUNC9 , // Function Key 9 // S2 10 - 17 - NOKEY , // - NOKEY , // - CTRL_R , // CTRL_R - CTRL_E , // CTRL_E - CTRL_D , // CTRL_D - CTRL_S , // CTRL_S - CTRL_X , // CTRL_X - CTRL_C , // CTRL_C + '7' , // KP 7 + '6' , // KP 6 + '5' , // KP 5 + '4' , // KP 4 + '3' , // KP 3 + '2' , // KP 2 + '1' , // KP 1 + '0' , // KP 0 // S3 18 - 1F - NOKEY , // - NOKEY , // - CTRL_Y , // CTRL_Y - CTRL_T , // CTRL_T - CTRL_G , // CTRL_G - CTRL_F , // CTRL_F - CTRL_V , // CTRL_V - CTRL_B , // CTRL_B + BREAKKEY , // Break Key + CURSRIGHT, // Cursor Right + CURSLEFT , // Cursor Left + CURSDOWN , // Cursor Down + CURSUP , // Cursor Up + CR , // Carriage Return + SPACE , // SPACE + TAB , // TAB // S4 20 - 27 - NOKEY , // - NOKEY , // - CTRL_I , // CTRL_I - CTRL_U , // CTRL_U - CTRL_J , // CTRL_J - CTRL_H , // CTRL_H - CTRL_N , // CTRL_N - ' ' , // SPACE + CTRL_G , // CTRL+G + CTRL_F , // CTRL+F + CTRL_E , // CTRL+E + CTRL_D , // CTRL+D + CTRL_C , // CTRL+C + CTRL_B , // CTRL+B + CTRL_A , // CTRL+A + CTRL_SLASH, // CTRL Slash // S5 28 - 2F - CTRL_UNDSCR, // CTRL+_ - NOKEY , // - CTRL_P , // CTRL_P - CTRL_O , // CTRL_O - CTRL_L , // CTRL_L - CTRL_K , // CTRL_K - NOKEY , // - CTRL_M , // CTRL_M + CTRL_O , // CTRL+O + CTRL_N , // CTRL+N + CTRL_M , // CTRL+M + CTRL_L , // CTRL+L + CTRL_K , // CTRL+K + CTRL_J , // CTRL+J + CTRL_I , // CTRL+I + CTRL_H , // CTRL+H // S6 30 - 37 - CTRL_CAPPA, // CTRL+^ - NOKEY , // - CTRL_LB , // CTRL+[ - CTRL_AT , // CTRL+@ - NOKEY , // - NOKEY , // - CTRL_SLASH, // CTRL+/ - NOKEY , // + CTRL_W , // CTRL+W + CTRL_V , // CTRL+V + CTRL_U , // CTRL+U + CTRL_T , // CTRL+T + CTRL_S , // CTRL+S + CTRL_R , // CTRL+R + CTRL_Q , // CTRL+Q + CTRL_P , // CTRL+P // S7 38 - 3F NOKEY , // NOKEY , // NOKEY , // NOKEY , // + CTRL_CAPPA, // CTRL+^ + CTRL_Z , // CTRL+Z + CTRL_Y , // CTRL+Y + CTRL_X , // CTRL+X + // S8 40 - 47 + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + CTRL_UNDSCR, // CTRL+_ + // S9 48 - 4F + NOKEY , // + CTRL_LB , // CTRL+[ + CTRL_SLASH, // CTRL+slash + CTRL_AT , // CTRL+@ + NOKEY , // + NOKEY , // + NOKEY , // NOKEY , // - CTRL_RB , // CTRL+] + // S10 50 - 57 NOKEY , // NOKEY , // - // S8 40 - 47 - Keypad keys. - NOKEY , // Keypad 8 - NOKEY , // 7 - NOKEY , // 5 - HOTKEY_LINUX, // 4 - Hotkey to invoke Linux mode. - HOTKEY_RFS40, // 2 - Hotkey to invoke RFS 40 mode. - HOTKEY_RFS80, // 1 - Hotkey to invoke RFS 80 mode. - NOKEY , // 00 - HOTKEY_ORIGINAL, // 0 - Hotkey to invoke original mode. - // S9 48 - 4F - Keypad keys. - NOKEY , // + - NOKEY , // 9 - NOKEY , // - - NOKEY , // 6 + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + CTRL_RB , // CTRL+] + // S11 58 - 5F NOKEY , // - HOTKEY_TZFS, // 3 - Hotkey to invoke TZFS mode. - NOKEY , - NOKEY // . + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // RVS + SHIFTLOCKKEY, // SHIFT + NOKEY , // SHIFT LOCK + GRAPHKEY // GRAPH }}, // MZ_2000 KANA {{ - // S0 00 - 07 - NOKEY , // BREAK/CTRL - NOKEY , // - NOKEY , // - NOKEY , // - NOKEY , // - NOKEY , // - GRAPHKEY , // DAKU TEN - NOKEY , // + // S0 00 - 07 + FUNC8 , // Function Key 8 + FUNC7 , // Function Key 7 + FUNC6 , // Function Key 6 + FUNC5 , // Function Key 5 + FUNC4 , // Function Key 4 + FUNC3 , // Function Key 3 + FUNC2 , // Function Key 2 + FUNC1 , // Function Key 1 // S1 08 - 0F - 0x35 , // HA - 0x77 , // TA - 0xD7 , // WA - 0xB3 , // YO - 0xB7 , // HANDAKU - NOKEY , - NOKEY , - NOKEY , + '-' , // KP - + '+' , // KP + + '.' , // KP . + DBLZERO , // KP Double Zero + '9' , // KP 9 + '8' , // KP 8 + FUNC10 , // Function Key 10 + FUNC9 , // Function Key 9 // S2 10 - 17 - 0x7C , // KA - 0x70 , // KE - 0x41 , // SHI - 0x31 , // KO - 0x39 , // HI - 0xA6 , // TE - 0x78 , // KI - 0xDD , // CHI + '7' , // KP 7 + '6' , // KP 6 + '5' , // KP 5 + '4' , // KP 4 + '3' , // KP 3 + '2' , // KP 2 + '1' , // KP 1 + '0' , // KP 0 // S3 18 - 1F - 0x3D , // FU - 0x5D , // MI - 0x6C , // MU - 0x56 , // ME - 0x1D , // RHI - 0x33 , // RA - 0xD5 , // HE - 0xB1 , // HO + BREAKKEY , // Break Key + CURSRIGHT, // Cursor Right + CURSLEFT , // Cursor Left + CURSDOWN , // Cursor Down + CURSUP , // Cursor Up + CR , // Carriage Return + SPACE , // SPACE + TAB , // TAB // S4 20 - 27 - 0x46 , // SA - 0x6E , // TO - 0xD9 , // THU - 0x48 , // SU - 0x74 , // KU - 0x43 , // SE - 0x4C , // SO - 0x73 , // MA + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // // S5 28 - 2F - 0x3F , // A - 0x36 , // I - 0x7E , // U - 0x3B , // E - 0x7A , // O - 0x1E , // NA - 0x5F , // NI - 0xA2 , // NU + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // // S6 30 - 37 - 0xD3 , // YO - 0x9F , // YU - 0xD1 , // YA - 0x00 , // SPACE - 0x9D , // NO - 0xA3 , // NE - 0xD0 , // RU - 0xB9 , // RE + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // // 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 - Keypad keys. - '8' , // Keypad 8 - '7' , // 7 - '5' , // 5 - '4' , // 4 - '2' , // 2 - '1' , // 1 - DBLZERO , // 00 - '0' , // 0 - // S9 48 - 4F - Keypad keys. - '+' , // + - '0' , // 9 - '-' , // - - '6' , // 6 + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + // S8 40 - 47 + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + // S9 48 - 4F + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // NOKEY , // - '3' , // 3 - NOKEY , - '.' // . + // S10 50 - 57 + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + // S11 58 - 5F + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // + NOKEY , // RVS + NOKEY , // SHIFT + SHIFTLOCKKEY, // SHIFT LOCK + GRAPHKEY // GRAPH }} }; @@ -1656,7 +1748,7 @@ static t_ansiKeyMap ansiKeySeq[] = { .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, .mode = KEYB_LOWERCASE, .cursorOn = 1, .flashTimer = 0L, .keyBuf[0] = 0x00, .keyBufPtr = 0, + const t_keyboard keyboardDefault = { .holdTimer = 0L, .autorepeat = 0, .cursorOn = 1, .flashTimer = 0L, .keyBuf[0] = 0x00, .keyBufPtr = 0, .mode = KEYB_LOWERCASE, .dualmode = KEYB_DUAL_NONE }; @@ -1683,7 +1775,7 @@ static t_ansiKeyMap ansiKeySeq[] = { }; // Keyboard control structure. Used to manage keyboard sweep, mapping and store. - const t_keyboard keyboardDefault = { .holdTimer = 0L, .autorepeat = 0, .mode = KEYB_LOWERCASE, .cursorOn = 1, .flashTimer = 0L, .keyBuf[0] = 0x00, .keyBufPtr = 0, + const t_keyboard keyboardDefault = { .holdTimer = 0L, .autorepeat = 0, .cursorOn = 1, .flashTimer = 0L, .keyBuf[0] = 0x00, .keyBufPtr = 0, .mode = KEYB_LOWERCASE, .dualmode = KEYB_DUAL_GRAPH }; @@ -1711,8 +1803,8 @@ static t_ansiKeyMap ansiKeySeq[] = { }; // Keyboard control structure. Used to manage keyboard sweep, mapping and store. - const t_keyboard keyboardDefault = { .holdTimer = 0L, .autorepeat = 0, .mode = KEYB_LOWERCASE, .cursorOn = 1, .flashTimer = 0L, .keyBuf[0] = 0x00, .keyBufPtr = 0, - .mode = KEYB_LOWERCASE, .dualmode = KEYB_DUAL_GRAPH + const t_keyboard keyboardDefault = { .holdTimer = 0L, .autorepeat = 0, .cursorOn = 1, .flashTimer = 0L, .keyBuf[0] = 0x00, .keyBufPtr = 0, + .mode = KEYB_LOWERCASE, .dualmode = KEYB_DUAL_NONE }; // Audio control structure. Used to manage audio output. @@ -1748,11 +1840,18 @@ static t_ansiKeyMap ansiKeySeq[] = { // uint8_t mzInitMBHardware(void) { + // Locals. + #if (TARGET_HOST_MZ2000 == 1) + uint32_t idx; + uint32_t idx2; + #endif + #if (TARGET_HOST_MZ700 == 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) // From the 1Z-013A monitor code, initialise the 8255 PIO. // WRITE_HARDWARE(1, MBADDR_KEYPF, 0x8A); // 10001010 CTRL WORD MODE0 @@ -1778,6 +1877,52 @@ uint8_t mzInitMBHardware(void) // Disable the hardware sound output. WRITE_HARDWARE(0, MBADDR_SUNDG, 0x00); // Sound could be enabled on start, disable it. + + #elif (TARGET_HOST_MZ2000 == 1) + // Initialise the Z80 PIO/8255 controllers. + // + WRITE_HARDWARE_IO(1, MBADDR_PPICTL, 0x82); // 8255 A=OUT B=IN C=OUT + WRITE_HARDWARE_IO(1, MBADDR_PPIC, 0x58); // BST=1 NST=0 OPEN=1 WRITE=1 + WRITE_HARDWARE_IO(1, MBADDR_PPIA, 0xF7); // All signals inactive, stop cassette. + WRITE_HARDWARE_IO(1, MBADDR_PIOCTLA, 0x0F); // Setup PIO A + WRITE_HARDWARE_IO(1, MBADDR_PIOCTLB, 0xCF); // Setup PIO B + WRITE_HARDWARE_IO(1, MBADDR_PIOCTLB, 0xFF); + + // Initialise video hardware. + // + WRITE_HARDWARE_IO(1, MBADDR_CRTGRPHSEL, 0x00); // Set Graphics VRAM to default, no access to GRAM. + WRITE_HARDWARE_IO(1, MBADDR_CRTBKCOLR, 0x00); // Set background colour on external output to black. + WRITE_HARDWARE_IO(1, MBADDR_GRAMCOLRSEL, 0x01); // Activate Blue graphics RAM bank for graphics operations (this is the default installed bank, red and green are optional). + WRITE_HARDWARE_IO(1, MBADDR_CRTGRPHPRIO, 0x07); // Enable all colour bank graphic output with character priority. + WRITE_HARDWARE_IO(1, MBADDR_PIOA, 0xD3); // 11010011 = VRAM paged in for characters, 40 char mode, keyboard strobe bank 3. + // A7 : H 0xD000:0xD7FF or 0xC000:0xFFFF VRAN paged in. + // A6 : H Select Character VRAM (H) or Graphics VRAM (L) + // A5 : H Select 80 char mode, 40 char mode = L + // A4 : L Select all key strobe lines active, for detection of any key press. + // A3-A0: Keyboard strobe lines + WRITE_HARDWARE_IO(1, MBADDR_PPIA, 0xFF); // Disable all PPI A signals. + // A7 : L APSS Search for next program + // A6 : L Automatic playback at end of rewind + // A5 : L Automatic rewind during playback(recording) + // A4 : L Invert Video + // A3 : L Stop Cassette + // A2 : L Play Cassette + // A1 : L Fast Forward + // A0 : L Rewind + // Clear VRAM. + // + WRITE_HARDWARE_IO(1, MBADDR_PIOA, 0x93); // Page in VRAM. + for(idx=3; idx > 0; idx--) + { + WRITE_HARDWARE_IO(1, MBADDR_GRAMCOLRSEL, idx); // Select graphics RAM bank to clear. + for(idx2=MBADDR_GRAMADDRL; idx2 < MBADDR_GRAMADDRL + 0x03E7F; idx2++) + { + WRITE_HARDWARE(1, idx2, 0x00); // Clear VRAM. + } + } + WRITE_HARDWARE_IO(1, MBADDR_PIOA, 0x13); // Disable VRAM. + #endif + return(0); } @@ -1820,7 +1965,7 @@ void mzBeep(uint32_t freq, uint32_t timeout) uint16_t freqDiv = TIMER_8253_MZ700_FREQ/freq; #endif - #if (TARGET_HOST_MZ2000 == 0) + #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 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) ); @@ -1906,12 +2051,15 @@ void mzClearDisplay(uint8_t mode, uint8_t updPos) break; } + // Enable Video RAM if required (based on target host). + ENABLE_VIDEO(); + // Clear the physical character display and attribute RAM. for(dstVRAMAddr=dstVRAMStartAddr, dstARAMAddr = dstARAMStartAddr; dstVRAMAddr <= dstVRAMEndAddr; dstVRAMAddr+=1, dstARAMAddr+=1) { // Clear both Video and Attribute RAM. - WRITE_HARDWARE(0, dstVRAMAddr, 0x00); - WRITE_HARDWARE(0, dstARAMAddr, display.displayAttr); + WRITE_VRAM_CHAR(dstVRAMAddr, 0x00); + WRITE_VRAM_ATTRIBUTE(dstARAMAddr, display.displayAttr); } // Clear the shadow display scrollback RAM. for(dstAddr = startIdx; dstAddr < endIdx; dstAddr++) @@ -1920,6 +2068,9 @@ void mzClearDisplay(uint8_t mode, uint8_t updPos) display.displayAttrBuf[dstAddr] = display.displayAttr; } + // Disable Video RAM. + DISABLE_VIDEO(); + return; } @@ -1954,12 +2105,15 @@ void mzClearLine(int row, int colStart, int colEnd, uint8_t updPos) dstVRAMEndAddr = dstVRAMStartAddr + newColEnd; dstARAMStartAddr = VIDEO_ARAM_BASE_ADDR+(newRow*display.maxBackingCol)+newColStart; + // Enable Video RAM if required (based on target host). + ENABLE_VIDEO(); + // Select 32bit or 8 bit clear depending on the start/end position. // for(dstVRAMAddr=dstVRAMStartAddr, dstARAMAddr = dstARAMStartAddr; dstVRAMAddr <= dstVRAMEndAddr; dstVRAMAddr+=1, dstARAMAddr+=1) { - WRITE_HARDWARE(0, dstVRAMAddr, 0x00); - WRITE_HARDWARE(0, dstARAMAddr, display.displayAttr); + WRITE_VRAM_CHAR(dstVRAMAddr, 0x00); + WRITE_VRAM_ATTRIBUTE(dstARAMAddr, display.displayAttr); } // Clear the shadow display scrollback RAM. @@ -1970,6 +2124,9 @@ void mzClearLine(int row, int colStart, int colEnd, uint8_t updPos) display.displayAttrBuf[dstAddr] = display.displayAttr; } + // Disable Video RAM. + DISABLE_VIDEO(); + // Update the display pointer if needed. if(updPos) { @@ -2014,17 +2171,31 @@ uint8_t mzSetDisplayWidth(uint8_t width) // Toggle the 40/80 bit according to requirements. if(width == 40) { + display.maxBackingCol = 40; + + #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) // Dummy read to enable access to control register. READ_HARDWARE_INIT(0, MBADDR_DSPCTL); WRITE_HARDWARE(0, MBADDR_DSPCTL, 0x00); - display.maxBackingCol = 40; + #elif (TARGET_HOST_MZ2000 == 1) + // Clear the 40/80 flag to set 40 column mode and use the DISABLE_VIDEO mode to reflect hardware change.. + display.hwVideoMode = display.hwVideoMode & 0xDF; + DISABLE_VIDEO(); + #endif } else { + display.maxBackingCol = 80; + + #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) // Dummy read to enable access to control register. READ_HARDWARE_INIT(0, MBADDR_DSPCTL); WRITE_HARDWARE(0, MBADDR_DSPCTL, VMMODE_80CHAR); - display.maxBackingCol = 80; + #elif (TARGET_HOST_MZ2000 == 1) + // Set the 40/80 flag to set 80 column mode and use the DISABLE_VIDEO mode to reflect hardware change.. + display.hwVideoMode = display.hwVideoMode | 0x20; + DISABLE_VIDEO(); + #endif } return(0); @@ -2039,13 +2210,19 @@ void mzRefreshDisplay(void) uint32_t dstARAMAddr; uint32_t dstVRAMAddr; + // Enable Video RAM if required (based on target host). + ENABLE_VIDEO(); + // Refresh the display with buffer window contents 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_HARDWARE(0, dstVRAMAddr, dispCodeMap[display.displayCharBuf[srcIdx]].dispCode); - WRITE_HARDWARE(0, dstARAMAddr, display.displayAttrBuf[srcIdx]); + WRITE_VRAM_CHAR(dstVRAMAddr, display.displayCharBuf[srcIdx]); + WRITE_VRAM_ATTRIBUTE(dstARAMAddr, display.displayAttrBuf[srcIdx]); } + + // Disable Video RAM. + DISABLE_VIDEO(); } // Method to scroll the display contents upwards, either because new data is being added to the bottom or for scrollback. @@ -2147,7 +2324,7 @@ uint8_t mzDeleteLines(uint8_t lines) // Locals. uint32_t srcAddr; uint32_t dstAddr; -static char testbuf[VC_DISPLAY_BUFFER_SIZE*8]; +//static char testbuf[VC_DISPLAY_BUFFER_SIZE*8]; // Sanity check. if(lines == 0 || lines > display.maxDisplayRow) @@ -2156,20 +2333,20 @@ static char testbuf[VC_DISPLAY_BUFFER_SIZE*8]; // Restore cursor character before scrolling. mzFlashCursor(CURSOR_RESTORE); - for(srcAddr=0; srcAddr < VC_DISPLAY_BUFFER_SIZE; srcAddr++) - { - if(srcAddr % display.maxBackingCol == 0) - { - if(srcAddr % 0x320 == 0) - { - pr_info("%s\n", testbuf); - testbuf[0] = 0x00; - } - sprintf(&testbuf[strlen(testbuf)], "\n%04x ", srcAddr); - } - sprintf(&testbuf[strlen(testbuf)], "%c", display.displayCharBuf[srcAddr]); - } - pr_info("%s\n", testbuf); +// for(srcAddr=0; srcAddr < VC_DISPLAY_BUFFER_SIZE; srcAddr++) +// { +// if(srcAddr % display.maxBackingCol == 0) +// { +// if(srcAddr % 0x320 == 0) +// { +// pr_info("%s\n", testbuf); +// testbuf[0] = 0x00; +// } +// sprintf(&testbuf[strlen(testbuf)], "\n%04x ", srcAddr); +// } +// sprintf(&testbuf[strlen(testbuf)], "%c", display.displayCharBuf[srcAddr]); +// } +// pr_info("%s\n", testbuf); // Starting line based on the current display row. srcAddr = ((display.displayRow+lines) * display.maxBackingCol); @@ -2181,7 +2358,7 @@ static char testbuf[VC_DISPLAY_BUFFER_SIZE*8]; display.displayCharBuf[dstAddr] = display.displayCharBuf[srcAddr]; display.displayAttrBuf[dstAddr] = display.displayAttrBuf[srcAddr]; } -pr_info("SrcAddr=%04x, DstAddr=%04x\n", srcAddr, dstAddr); +//pr_info("SrcAddr=%04x, DstAddr=%04x\n", srcAddr, dstAddr); // Fill end of buffer with space. for(; dstAddr < VC_DISPLAY_BUFFER_SIZE; dstAddr++) { @@ -2189,20 +2366,20 @@ pr_info("SrcAddr=%04x, DstAddr=%04x\n", srcAddr, dstAddr); display.displayAttrBuf[dstAddr] = display.displayAttr; } - for(srcAddr=0; srcAddr < VC_DISPLAY_BUFFER_SIZE; srcAddr++) - { - if(srcAddr % display.maxBackingCol == 0) - { - if(srcAddr % 0x320 == 0) - { - pr_info("%s\n", testbuf); - testbuf[0] = 0x00; - } - sprintf(&testbuf[strlen(testbuf)], "\n%04x ", srcAddr); - } - sprintf(&testbuf[strlen(testbuf)], "%c", display.displayCharBuf[srcAddr]); - } - pr_info("%s\n", testbuf); +// for(srcAddr=0; srcAddr < VC_DISPLAY_BUFFER_SIZE; srcAddr++) +// { +// if(srcAddr % display.maxBackingCol == 0) +// { +// if(srcAddr % 0x320 == 0) +// { +// pr_info("%s\n", testbuf); +// testbuf[0] = 0x00; +// } +// sprintf(&testbuf[strlen(testbuf)], "\n%04x ", srcAddr); +// } +// sprintf(&testbuf[strlen(testbuf)], "%c", display.displayCharBuf[srcAddr]); +// } +// pr_info("%s\n", testbuf); // Refresh the display with buffer window contents mzRefreshDisplay(); @@ -2360,14 +2537,22 @@ int mzPutChar(char c) // Output to display if flag set. if(output) { + // Enable Video RAM if required (based on target host). + ENABLE_VIDEO(); + // Output character using default attributes. dispMemAddr = VIDEO_VRAM_BASE_ADDR + (display.displayRow * display.maxBackingCol) + display.displayCol; - WRITE_HARDWARE(0, dispMemAddr, (char)dispCodeMap[(int)c].dispCode); + WRITE_VRAM_CHAR(dispMemAddr, (char)c); display.displayCharBuf[(display.backingRow * display.maxBackingCol) + display.displayCol] = c; // dispMemAddr = VIDEO_ARAM_BASE_ADDR + (display.displayRow * display.maxBackingCol) + display.displayCol; - WRITE_HARDWARE(0, dispMemAddr, display.displayAttr); + WRITE_VRAM_ATTRIBUTE(dispMemAddr, display.displayAttr); display.displayAttrBuf[(display.backingRow * display.maxBackingCol) + display.displayCol] = display.displayAttr; + + // Disable Video RAM. + DISABLE_VIDEO(); + + // Check for end of line conditions, scroll if necessary. if(++display.displayCol >= display.maxBackingCol) { if(display.lineWrap) @@ -2408,14 +2593,22 @@ int mzPutRaw(char c) // Variables and locals. uint32_t dispMemAddr; + // Enable Video RAM if required (based on target host). + ENABLE_VIDEO(); + // Output character using default attributes. dispMemAddr = VIDEO_VRAM_BASE_ADDR + (display.displayRow * display.maxBackingCol) + display.displayCol; - WRITE_HARDWARE(0, dispMemAddr, (char)dispCodeMap[(int)c].dispCode); + WRITE_VRAM_CHAR(dispMemAddr, (char)c); display.displayCharBuf[(display.backingRow * display.maxBackingCol) + display.displayCol] = c; // dispMemAddr = VIDEO_ARAM_BASE_ADDR + (display.displayRow * display.maxBackingCol) + display.displayCol; - WRITE_HARDWARE(0, dispMemAddr, display.displayAttr); + WRITE_VRAM_ATTRIBUTE(dispMemAddr, display.displayAttr); display.displayAttrBuf[(display.backingRow * display.maxBackingCol) + display.displayCol] = display.displayAttr; + + // Disable Video RAM. + DISABLE_VIDEO(); + + // Check for end of line conditions, scroll if necessary. if(++display.displayCol >= display.maxBackingCol) { if(display.lineWrap) @@ -3295,6 +3488,10 @@ uint8_t mzFlashCursor(enum CURSOR_STATES state) // Locals. uint32_t dispMemAddr = VIDEO_VRAM_BASE_ADDR + (display.displayRow * display.maxBackingCol) + display.displayCol; uint16_t srcIdx = (display.backingRow * display.maxBackingCol) + display.displayCol; + uint8_t cursorChr; + + // Enable Video RAM if required (based on target host). + ENABLE_VIDEO(); // Action according to request. switch(state) @@ -3305,7 +3502,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_HARDWARE(0, dispMemAddr, dispCodeMap[display.displayCharBuf[srcIdx]].dispCode); + WRITE_VRAM_CHAR(dispMemAddr, display.displayCharBuf[srcIdx]); } keyboard.cursorOn = 0; keyboard.displayCursor = 0; @@ -3321,7 +3518,7 @@ uint8_t mzFlashCursor(enum CURSOR_STATES state) case CURSOR_RESTORE: if(keyboard.displayCursor == 1) { - WRITE_HARDWARE(0, dispMemAddr, dispCodeMap[display.displayCharBuf[srcIdx]].dispCode); + WRITE_VRAM_CHAR(dispMemAddr, display.displayCharBuf[srcIdx]); keyboard.displayCursor = 0; } break; @@ -3337,23 +3534,30 @@ uint8_t mzFlashCursor(enum CURSOR_STATES state) switch(keyboard.mode) { case KEYB_LOWERCASE: - WRITE_HARDWARE(0, dispMemAddr, CURSOR_UNDERLINE); + cursorChr = CURSOR_CHR_UNDERLINE; break; case KEYB_CAPSLOCK: - WRITE_HARDWARE(0, dispMemAddr, CURSOR_BLOCK); + cursorChr = CURSOR_CHR_BLOCK; break; case KEYB_SHIFTLOCK: + cursorChr = CURSOR_CHR_THICK_BLOCK; + break; + case KEYB_GRAPHMODE: default: - WRITE_HARDWARE(0, dispMemAddr, CURSOR_THICK_BLOCK); + cursorChr = CURSOR_CHR_GRAPH; break; } + WRITE_VRAM_CHAR(dispMemAddr, cursorChr); } else { - WRITE_HARDWARE(0, dispMemAddr, dispCodeMap[display.displayCharBuf[srcIdx]].dispCode); + WRITE_VRAM_CHAR(dispMemAddr, display.displayCharBuf[srcIdx]); } } break; } + + // Disable Video RAM. + DISABLE_VIDEO(); return(0); } @@ -3386,21 +3590,21 @@ uint8_t mzSweepKeys(void) uint64_t delay; // Sequence through the strobe lines and read back the scan data into the buffer. - for(strobe=0xF0; strobe < 0xFA; strobe++) + for(strobe=0xF0; strobe < (0xF0+KEY_SCAN_ROWS); strobe++) { // Output the keyboard strobe. - WRITE_HARDWARE(0, MBADDR_KEYPA, strobe); + WRITE_KEYB_STROBE(strobe); // Slight delay to allow for bounce. delay = ktime_get_ns(); while((ktime_get_ns() - delay) < 1000000); // Read the scan lines. - READ_HARDWARE_INIT(0, MBADDR_KEYPB); - keyboard.scanbuf[0][strobe-0xF0] = ctrl.suspendIO == 0 ? READ_HARDWARE() : 0xFF; + READ_KEYB_INIT(); + keyboard.scanbuf[0][strobe-0xF0] = ctrl.suspendIO == 0 ? READ_KEYB() : 0xFF; } // Now look for active keys. - for(strobeIdx=0; strobeIdx < 10; strobeIdx++) + for(strobeIdx=0; strobeIdx < KEY_SCAN_ROWS; strobeIdx++) { // Skip over modifier keys. //if(strobeIdx == 8) continue; @@ -3499,21 +3703,21 @@ uint8_t mzSweepKeys(void) #elif (TARGET_HOST_MZ2000 == 1) // Check for modifiers. // - if((keyboard.scanbuf[0][0] & 0x01) == 0) + if((keyboard.scanbuf[0][11] & 0x04) == 0) { keyboard.shiftKey = 1; } else { keyboard.shiftKey = 0; } - if((keyboard.scanbuf[0][0] & 0x80) == 0 && keyboard.shiftKey == 0) + if((keyboard.scanbuf[0][11] & 0x08) == 0 && keyboard.shiftKey == 0) { keyboard.ctrlKey = 1; } else { keyboard.ctrlKey = 0; } - if((keyboard.scanbuf[0][0] & 0x80) == 0 && keyboard.shiftKey == 1) + if((keyboard.scanbuf[0][3] & 0x01) == 0 && keyboard.shiftKey == 1) { keyboard.breakKey = 1; } else @@ -3559,7 +3763,7 @@ int mzGetKey(uint8_t mode) mzSweepKeys(); // Run through the strobe sequence and identify any pressed keys, mapping to an ASCII value for return. - for(strobeIdx=0; strobeIdx < 10; strobeIdx++) + for(strobeIdx=0; strobeIdx < KEY_SCAN_ROWS; strobeIdx++) { // Skip over modifier keys. //if(strobeIdx == 8) continue; @@ -3618,9 +3822,15 @@ int mzGetKey(uint8_t mode) retcode = -1; break; + // Shift lock when present on host. + case SHIFTLOCKKEY: + keyboard.mode = keyboard.mode == KEYB_LOWERCASE ? KEYB_SHIFTLOCK : keyboard.mode == KEYB_SHIFTLOCK ? KEYB_CAPSLOCK : KEYB_LOWERCASE; + retcode = -1; + break; + // Switch to graphics mode character set. case GRAPHKEY: - keyboard.mode = (keyboard.mode == KEYB_GRAPHMODE ? KEYB_CAPSLOCK : KEYB_GRAPHMODE); + keyboard.mode = (keyboard.mode == KEYB_GRAPHMODE ? KEYB_LOWERCASE : KEYB_GRAPHMODE); retcode = -1; break; diff --git a/software/FusionX/src/ttymz/sharpmz.h b/software/FusionX/src/ttymz/sharpmz.h index 426791f7b..043d225dc 100755 --- a/software/FusionX/src/ttymz/sharpmz.h +++ b/software/FusionX/src/ttymz/sharpmz.h @@ -66,7 +66,7 @@ // Video display constants. #define VC_MAX_ROWS 25 // Maximum number of rows on display. -#if defined(TARGET_HOST_MZ700) +#if (TARGET_HOST_MZ700 == 1) #define VC_MAX_COLUMNS 40 // Maximum number of columns on display. #else #define VC_MAX_COLUMNS 80 // Maximum number of columns on display. @@ -78,10 +78,20 @@ #define KEYB_AUTOREPEAT_INITIAL_TIME 800 // Time in milliseconds before starting autorepeat. #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 CURSOR_THICK_BLOCK 0x43 // Thick block cursor for lower case CAPS OFF -#define CURSOR_BLOCK 0xEF // Block cursor for SHIFT Lock. -#define CURSOR_UNDERLINE 0x3E // Thick underscore for CAPS Lock. #define MAX_KEYB_BUFFER_SIZE 32 // Maximum size of the keyboard buffer. +#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 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_GRAPH 0xFF // Graphic cursor for GRAPH mode. + #define CURSOR_CHR_UNDERLINE 0x3E // 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. + #define CURSOR_CHR_BLOCK 0x82 // Block cursor for CAPS Lock. + #define CURSOR_CHR_GRAPH 0x93 // Graphic cursor for GRAPH mode. + #define CURSOR_CHR_UNDERLINE 0x1F // Underline for lower case CAPS OFF. +#endif // Audio constants. #define TIMER_8253_MZ80A_FREQ 2000000 // Base input frequency of Timer 0 for square wave generation. @@ -134,7 +144,7 @@ #define VMATTR_BG_MASKOUT 0xF8 // Mask to filter out background attribute. #define VMATTR_BG_MASKIN 0x07 // Mask to filter out background attribute. -// Sharp MZ constants. +// Sharp MZ-80A/700 constants. // #define MBADDR_KEYPA 0xE000 // Mainboard 8255 Port A #define MBADDR_KEYPB 0xE001 // Mainboard 8255 Port B @@ -156,6 +166,31 @@ #define MBADDR_SCLBASE 0xE2 // High byte scroll base. #define MBADDR_DSPCTL 0xDFFF // Display 40/80 select register (bit 7) +// Sharp MZ-2000 constants. +#define MBADDR_FDC 0x0D8 // MB8866 IO Region 0D8h - 0DBh +#define MBADDR_FDC_CR MBADDR_FDC + 0x00 // Command Register +#define MBADDR_FDC_STR MBADDR_FDC + 0x00 // Status Register +#define MBADDR_FDC_TR MBADDR_FDC + 0x01 // Track Register +#define MBADDR_FDC_SCR MBADDR_FDC + 0x02 // Sector Register +#define MBADDR_FDC_DR MBADDR_FDC + 0x03 // Data Register +#define MBADDR_FDC_MOTOR MBADDR_FDC + 0x04 // DS[0-3] and Motor control. 4 drives DS= BIT 0 -> Bit 2 = Drive number, 2=1,1=0,0=0 DS0, 2=1,1=0,0=1 DS1 etc + // bit 7 = 1 MOTOR ON LOW (Active) +#define MBADDR_FDC_SIDE MBADDR_FDC + 0x05 // Side select, Bit 0 when set = SIDE SELECT LOW, +#define MBADDR_FDC_DDEN MBADDR_FDC + 0x06 // Double density enable, 0 = double density, 1 = single density disks. +#define MBADDR_PPIA 0x0E0 // 8255 Port A +#define MBADDR_PPIB 0x0E1 // 8255 Port B +#define MBADDR_PPIC 0x0E2 // 8255 Port C +#define MBADDR_PPICTL 0x0E3 // 8255 Control Port +#define MBADDR_PIOA 0x0E8 // Z80 PIO Port A +#define MBADDR_PIOCTLA 0x0E9 // Z80 PIO Port A Control Port +#define MBADDR_PIOB 0x0EA // Z80 PIO Port B +#define MBADDR_PIOCTLB 0x0EB // Z80 PIO Port B Control Port +#define MBADDR_CRTBKCOLR 0x0F4 // Configure external CRT background colour. +#define MBADDR_CRTGRPHPRIO 0x0F5 // Graphics priority register, character or a graphics colour has front display priority. +#define MBADDR_CRTGRPHSEL 0x0F6 // Graphics output select on CRT or external CRT +#define MBADDR_GRAMCOLRSEL 0x0F7 // Graphics RAM colour bank select. +#define MBADDR_GRAMADDRL 0x0C000 // Graphics RAM base address. + //Common character definitions. #define SCROLL 0x01 // Set scroll direction UP. #define BELL 0x07 @@ -201,7 +236,7 @@ #define CTRL_Z 0x1A #define ESC 0x1B #define CTRL_SLASH 0x1C -#define CTRL_LB 0x1B +#define CTRL_LB 0x1 #define CTRL_RB 0x1D #define CTRL_CAPPA 0x1E #define CTRL_UNDSCR 0x1F @@ -216,15 +251,16 @@ #define FUNC8 0x87 #define FUNC9 0x88 #define FUNC10 0x89 -#define PAGEUP 0xE0 -#define PAGEDOWN 0xE1 -#define CURHOMEKEY 0xE2 -#define ALPHAGRAPHKEY 0xE3 -#define HOTKEY_ORIGINAL 0xE8 -#define HOTKEY_RFS80 0xE9 -#define HOTKEY_RFS40 0xEA -#define HOTKEY_TZFS 0xEB -#define HOTKEY_LINUX 0xEC +#define HOTKEY_ORIGINAL 0xE0 +#define HOTKEY_RFS80 0xE1 +#define HOTKEY_RFS40 0xE2 +#define HOTKEY_TZFS 0xE3 +#define HOTKEY_LINUX 0xE4 +#define PAGEUP 0xE8 +#define PAGEDOWN 0xE9 +#define CURHOMEKEY 0xEA +#define ALPHAGRAPHKEY 0xEB +#define SHIFTLOCKKEY 0xEC #define NOKEY 0xF0 #define CURSRIGHT 0xF1 #define CURSLEFT 0xF2 @@ -263,6 +299,58 @@ #define READ_HARDWARE() (\ z80io_PRL_Read8(1)\ ) +#define WRITE_HARDWARE_IO(__force__,__addr__,__data__)\ + {\ + if(!ctrl.suspendIO || __force__ == 1)\ + {\ + SPI_SEND32((uint32_t)__addr__ << 16 | __data__ << 8 | CPLD_CMD_WRITEIO_ADDR);\ + }\ + } +#define READ_HARDWARE_IO_INIT(__force__,__addr__)\ + {\ + if(!ctrl.suspendIO || __force__ == 1)\ + {\ + SPI_SEND32((uint32_t)__addr__ << 16 | 0x00 << 8 | CPLD_CMD_READIO_ADDR);\ + while(CPLD_READY() == 0);\ + }\ + } +#define READ_HARDWARE_IO() (\ + z80io_PRL_Read8(1)\ + ) +// Video memory macros, allows for options based on host hardware - All Sharp MZ series are very similar. +#if (TARGET_HOST_MZ2000 == 1) + // A7 : H 0xD000:0xD7FF or 0xC000:0xFFFF VRAM paged in. + // A6 : H Select Character VRAM (H) or Graphics VRAM (L) + // A5 : H Select 80 char mode, 40 char mode = L + // A4 : L Select all key strobe lines active, for detection of any key press. + // A3-A0: Keyboard strobe lines + #define ENABLE_VIDEO() {\ + display.hwVideoMode = (display.hwVideoMode & 0x3F) | 0xC0;\ + WRITE_HARDWARE_IO(0, MBADDR_PIOA, display.hwVideoMode);\ + } + #define DISABLE_VIDEO() {\ + 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_ATTRIBUTE(__addr__,__data__) {} + #define WRITE_KEYB_STROBE(__data__)\ + {\ + display.hwVideoMode = (display.hwVideoMode & 0xF0) | 0x10 | (__data__ & 0x0F);\ + WRITE_HARDWARE_IO(0, MBADDR_PIOA, display.hwVideoMode );\ + } + #define READ_KEYB_INIT() READ_HARDWARE_IO_INIT(0, MBADDR_PIOB) + #define READ_KEYB() READ_HARDWARE_IO() +#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 READ_KEYB_INIT() READ_HARDWARE_INIT(0, MBADDR_KEYPB) + #define READ_KEYB() READ_HARDWARE() +#endif + // Cursor flash mechanism control states. @@ -316,7 +404,7 @@ typedef struct { // Mapping table from keyboard scan codes to Sharp MZ keys. // typedef struct { - uint8_t scanCode[80]; + uint8_t scanCode[KEY_SCAN_ROWS*8]; } t_scanCodeMap; // Mapping table of a sharp keycode to an ANSI escape sequence string. @@ -349,16 +437,19 @@ typedef struct { uint8_t lineWrap; // Wrap line at display edge (1) else stop printing at display edge. uint8_t useAnsiTerm; // Enable (1) Ansi Terminal Emulator, (0) disable. uint8_t inDebug; // Prevent recursion when outputting debug information. + + // Working variables. + uint8_t hwVideoMode; // Physical configuration of the video control register. } t_displayBuffer; // Structure for maintaining the Sharp MZ keyboard parameters and data. Used to retrieve and map a key along with associated // attributes such as cursor flashing. // typedef struct { - uint8_t scanbuf[2][10]; - uint8_t keydown[10]; - uint8_t keyup[10]; - uint8_t keyhold[10]; + uint8_t scanbuf[2][KEY_SCAN_ROWS]; + uint8_t keydown[KEY_SCAN_ROWS]; + uint8_t keyup[KEY_SCAN_ROWS]; + uint8_t keyhold[KEY_SCAN_ROWS]; uint32_t holdTimer; uint8_t breakKey; // Break key pressed. uint8_t ctrlKey; // Ctrl key pressed. @@ -398,10 +489,10 @@ typedef struct { uint8_t setDisplayMode; // Display mode command detected. uint8_t setExtendedMode; // Extended mode command detected. uint8_t charbuf[80]; // Storage for the parameter characters as they are received. - uint16_t param[10]; // Parsed paraemters. + uint16_t param[10]; // Parsed parameters. uint8_t saveRow; // Store the current row when requested. uint8_t saveCol; // Store the current column when requested. - uint8_t saveDisplayRow; // Store the current display buffer row when requested. + uint8_t saveDisplayRow; // Store the current display buffer row when requested. } t_AnsiTerm; // Application execution constants. diff --git a/software/FusionX/src/ttymz/ttymz.c b/software/FusionX/src/ttymz/ttymz.c index cd8d49ceb..1694b5a01 100644 --- a/software/FusionX/src/ttymz/ttymz.c +++ b/software/FusionX/src/ttymz/ttymz.c @@ -18,6 +18,7 @@ // switching between a Linux session and a Z80 session, the idea // being the TTY will continue to run within the mirrored framebuffer // and when reselected, refresh the hardware screen. +// Apr 2023 - v1.1 Updated to include MZ-2000 mode. // // Notes: See Makefile to enable/disable conditional components // diff --git a/software/FusionX/src/ttymz/ttymz.h b/software/FusionX/src/ttymz/ttymz.h index c1cba5553..e75488aa6 100644 --- a/software/FusionX/src/ttymz/ttymz.h +++ b/software/FusionX/src/ttymz/ttymz.h @@ -11,6 +11,7 @@ // Copyright: (c) 2019-2023 Philip Smart // // History: Feb 2023 - v1.0 Initial write of the Sharp MZ tty driver software. +// Apr 2023 - v1.1 Updated to include MZ-2000 mode. // // Notes: See Makefile to enable/disable conditional components // @@ -35,8 +36,8 @@ #define DRIVER_LICENSE "GPL" #define DRIVER_AUTHOR "Philip D Smart" #define DRIVER_DESCRIPTION "Sharp MZ TTY Driver" -#define DRIVER_VERSION "v1.01" -#define DRIVER_VERSION_DATE "Mar 2023" +#define DRIVER_VERSION "v1.1" +#define DRIVER_VERSION_DATE "Apr 2023" #define DRIVER_COPYRIGHT "(C) 2018-2023" #define DEVICE_NAME "ttymz" #define DRIVER_NAME "SharpMZ_tty" diff --git a/software/FusionX/src/z80drv/src/k64fcpu.c b/software/FusionX/src/z80drv/src/k64fcpu.c index 07eb94e87..59a1f158d 100644 --- a/software/FusionX/src/z80drv/src/k64fcpu.c +++ b/software/FusionX/src/z80drv/src/k64fcpu.c @@ -19,6 +19,7 @@ // History: Feb 2023 v1.0 - Source copied from zSoft and modified to run as a daemon, stripping // 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. // // Notes: See Makefile to enable/disable conditional components // @@ -64,7 +65,7 @@ extern "C" { #include "z80driver.h" #include "tzpu.h" -#define VERSION "1.01" +#define VERSION "1.02" #define AUTHOR "P.D.Smart" #define COPYRIGHT "(c) 2018-23" @@ -2402,6 +2403,7 @@ void processServiceRequest(void) // Update the service control record address according to memory mode. // z80Control.svcControlAddr = getServiceAddr(); +printf("Service Addr:%04x\n", z80Control.svcControlAddr); // Get the command and associated parameters. copyFromZ80((uint8_t *)&svcControl, z80Control.svcControlAddr, TZSVC_CMD_SIZE, TRANZPUTER); @@ -2411,7 +2413,7 @@ void processServiceRequest(void) { copyFromZ80((uint8_t *)&svcControl.sector, z80Control.svcControlAddr+TZSVC_CMD_SIZE, TZSVC_SECTOR_SIZE, TRANZPUTER); } - +printf("Received command:%02x\n", svcControl.cmd); //memoryDump((uint32_t)&svcControl, sizeof(svcControl), 5, 8, 0, 0); // Check this is a valid request. if(svcControl.result == TZSVC_STATUS_REQUEST) @@ -2560,7 +2562,7 @@ void processServiceRequest(void) break; // Load the MZ-2000 IPL ROM into memory for compatibility switch. - case TZSVC_CMD_LOAD2000IPL: + case TZSVC_CMD_LOAD2KIPL: loadBIOS((const char *)OS_BASE_DIR TZSVC_DEFAULT_TZFS_DIR "/" MZ_ROM_MZ2000_IPL, MZ_MROM_ADDR); // Set the frequency of the CPU if we are emulating the hardware. @@ -2570,6 +2572,21 @@ void processServiceRequest(void) setZ80CPUFrequency(MZ_2000_CPU_FREQ, 1); } break; + + // Load the MZ-2000 Basic 1Z001 into memory. + case TZSVC_CMD_LOAD2KBASIC1: + loadBIOS((const char *)OS_BASE_DIR TZSVC_DEFAULT_ROM_DIR "/" MZ_ROM_MZ2000_1Z001, MZ_MROM_ADDR); + break; + + // Load the MZ-2000 Basic 1Z002 into memory. + case TZSVC_CMD_LOAD2KBASIC2: + loadBIOS((const char *)OS_BASE_DIR TZSVC_DEFAULT_ROM_DIR "/" MZ_ROM_MZ2000_1Z002, MZ_MROM_ADDR); + break; + + // Load the MZ-2000 1Z001M Monitor ROM into memory. + case TZSVC_CMD_LOAD2KMON: + loadBIOS((const char *)OS_BASE_DIR TZSVC_DEFAULT_ROM_DIR "/" MZ_ROM_MZ2000_1Z001M, MZ_MROM_ADDR); + break; // Load TZFS upon request. This service is for the MZ-80B/MZ-2000 which dont have a monitor BIOS installed and TZFS isnt loaded upon reset but rather through user request. case TZSVC_CMD_LOADTZFS: @@ -2709,6 +2726,8 @@ void processServiceRequest(void) printf("Error: Unsupported Raw SD Write feature.\n"); break; + // Load + // Command to exit from TZFS and return machine to original mode. case TZSVC_CMD_EXIT: // Disable secondary frequency. diff --git a/software/FusionX/src/z80drv/src/sharpbiter.c b/software/FusionX/src/z80drv/src/sharpbiter.c index 7236371fc..1b48281e1 100644 --- a/software/FusionX/src/z80drv/src/sharpbiter.c +++ b/software/FusionX/src/z80drv/src/sharpbiter.c @@ -20,6 +20,7 @@ // Copyright: (c) 2019-2023 Philip Smart // // History: Feb 2023 v1.0 - Initial write. +// Apr 2023 v1.1 - Updates to include MZ-2000. // // Notes: See Makefile to enable/disable conditional components // diff --git a/software/FusionX/src/z80drv/src/tzpu.h b/software/FusionX/src/z80drv/src/tzpu.h index e0d9992f9..88bb8381c 100755 --- a/software/FusionX/src/z80drv/src/tzpu.h +++ b/software/FusionX/src/z80drv/src/tzpu.h @@ -321,7 +321,11 @@ // Service request constants. // -#define TZSVC_CMD_STRUCT_ADDR_TZFS 0x0ED80 // Address of the command structure within TZFS - exists in 64K Block 0. +#if (TARGET_HOST_MZ2000 == 1) + #define TZSVC_CMD_STRUCT_ADDR_TZFS 0x06D80 // Address of the command structure within MZ-2000 IPL Mode +#else + #define TZSVC_CMD_STRUCT_ADDR_TZFS 0x0ED80 // Address of the command structure within TZFS - exists in 64K Block 0. +#endif #define TZSVC_CMD_STRUCT_ADDR_CPM 0x4F560 // Address of the command structure within CP/M - exists in 64K Block 4. #define TZSVC_CMD_STRUCT_ADDR_MZ700 0x6FD80 // Address of the command structure within MZ700 compatible programs - exists in 64K Block 6. #define TZSVC_CMD_STRUCT_ADDR_ZOS 0x11FD80 // 0x7FD80 // Address of the command structure for zOS use, exists in shared memory rather than FPGA. Spans top of block 6 and all of block 7. @@ -351,7 +355,10 @@ #define TZSVC_CMD_LOAD700BIOS80 0x23 // Service command requesting that the MZ700 1Z-013A 80 column patched BIOS is loaded. #define TZSVC_CMD_LOAD80BIPL 0x24 // Service command requesting the MZ-80B IPL is loaded. #define TZSVC_CMD_LOAD800BIOS 0x25 // Service command requesting that the MZ800 9Z-504M BIOS is loaded. -#define TZSVC_CMD_LOAD2000IPL 0x26 // Service command requesting the MZ-2000 IPL is loaded. +#define TZSVC_CMD_LOAD2KIPL 0x26 // Service command requesting the MZ-2000 IPL is loaded. +#define TZSVC_CMD_LOAD2KBASIC1 0x27 // Service command to load BASIC 1Z-001 for the MZ-2000. +#define TZSVC_CMD_LOAD2KBASIC2 0x28 // Service command to load BASIC 1Z-002 for the MZ-2000. +#define TZSVC_CMD_LOAD2KMON 0x29 // Service command to load Monitor 1Z001M for the MZ-2000 IPL. #define TZSVC_CMD_LOADTZFS 0x2F // Service command requesting the loading of TZFS. This service is for machines which normally dont have a monitor BIOS. ie. MZ-80B/MZ-2000 and manually request TZFS. #define TZSVC_CMD_LOADBDOS 0x30 // Service command to reload CPM BDOS+CCP. #define TZSVC_CMD_ADDSDDRIVE 0x31 // Service command to attach a CPM disk to a drive number. @@ -379,6 +386,7 @@ #define TZSVC_CMD_SD_WRITESECTOR 0x62 // Service command to provide raw write access to the underlying SD card. #define TZSVC_CMD_EXIT 0x7F // Service command to terminate TZFS and restart the machine in original mode. #define TZSVC_DEFAULT_TZFS_DIR "TZFS" // Default directory where TZFS files are stored. +#define TZSVC_DEFAULT_ROM_DIR "ROMS" // Default directory where ROM files are stored. #define TZSVC_DEFAULT_CPM_DIR "CPM" // Default directory where CPM files are stored. #define TZSVC_DEFAULT_MZF_DIR "MZF" // Default directory where MZF files are stored. #define TZSVC_DEFAULT_CAS_DIR "CAS" // Default directory where BASIC CASsette files are stored. @@ -423,6 +431,9 @@ #define MZ_ROM_MZ2000_IPL_TZPU "MZ2000_IPL_TZPU.rom" // Modified IPL ROM for the tranZPUter running on the Sharp MZ-2000. #define MZ_ROM_MZ2000_CGROM "MZ2000_CGROM.rom" // MZ-2000 CGROM. #define MZ_ROM_TZFS "tzfs.rom" // tranZPUter Filing System ROM. +#define MZ_ROM_MZ2000_1Z001 "mz2000_basic_1z001.rom" // MZ-2000 BASIC 1Z-001. +#define MZ_ROM_MZ2000_1Z002 "mz2000_basic_1z002.rom" // MZ-2000 BASIC 1Z-002. +#define MZ_ROM_MZ2000_1Z001M "mz2000_mon_1z001m.rom" // MZ-2000 BASIC 1Z-002. // CP/M constants. // diff --git a/software/FusionX/src/z80drv/src/z80driver.c b/software/FusionX/src/z80drv/src/z80driver.c index 42a3bc3b2..66de9d08c 100644 --- a/software/FusionX/src/z80drv/src/z80driver.c +++ b/software/FusionX/src/z80drv/src/z80driver.c @@ -13,31 +13,32 @@ // Copyright: (c) 2019-2023 Philip Smart // (c) 1999-2023 Manuel Sainz de Baranda y Goñi // -// History: Oct 2022 - v1.0 Initial write of the z80 kernel driver software. -// Jan 2023 - v1.1 Added MZ-2000/MZ-80A modes. There are serious limitations with the -// SSD202 I/O. The I/O Bus appears to run at 72MHz and the GPIO bits -// are split across 2x16 registers per bit. This limits 8bit read -// speed to < 2MB/s, write speed slower due to select signal. Thus it -// is not feasible to run a program in the host memory at full speed. -// Virtual (Kernel) memory is used for all programs and host is only -// accessed for specific reasons, such as the MZ-80A FDD Bios which -// changes according to state of READY signal. I/O operations have to -// use lookahead during fetch cycle to steal time in order to meet timings. -// If SigmaStar make a newer SSD or an alternative becomes available which -// has I/O bus running at 4x speed or has 32bit per cycle GPIO access then -// the design needs to be upgraded to fulfill the idea of running programs -// in host memory at full speed. -// Feb 2023 - v1.2 Added MZ-80A Rom Filing System device driver. This allows the FusionX -// hosted in an MZ-80A to run the original RFS Monitor and software. -// Feb 2023 - v1.3 Added tranZPUter SW device driver. This allows the FusionX hosted -// in any supported host to run TZFS and the updated applications -// such as CP/M, SA-5510 Basic, MS-Basic etc. Adding this device driver -// prepares the ground to add the SOM GPU as the Video emulation of -// the Sharp machines. -// Mar 2023 - v1.4 With the advent of the PCW-8XXX series, seperated distinct machine -// configurations into device driver modules, which are only built -// if same as the target machine. This then allows the z80 driver to be -// a vanilla Z80 or customisations for hosts pulled in. +// History: Oct 2022 - v1.0 Initial write of the z80 kernel driver software. +// Jan 2023 - v1.1 Added MZ-2000/MZ-80A modes. There are serious limitations with the +// SSD202 I/O. The I/O Bus appears to run at 72MHz and the GPIO bits +// are split across 2x16 registers per bit. This limits 8bit read +// speed to < 2MB/s, write speed slower due to select signal. Thus it +// is not feasible to run a program in the host memory at full speed. +// Virtual (Kernel) memory is used for all programs and host is only +// accessed for specific reasons, such as the MZ-80A FDD Bios which +// changes according to state of READY signal. I/O operations have to +// use lookahead during fetch cycle to steal time in order to meet timings. +// If SigmaStar make a newer SSD or an alternative becomes available which +// has I/O bus running at 4x speed or has 32bit per cycle GPIO access then +// the design needs to be upgraded to fulfill the idea of running programs +// in host memory at full speed. +// Feb 2023 - v1.2 Added MZ-80A Rom Filing System device driver. This allows the FusionX +// hosted in an MZ-80A to run the original RFS Monitor and software. +// Feb 2023 - v1.3 Added tranZPUter SW device driver. This allows the FusionX hosted +// in any supported host to run TZFS and the updated applications +// such as CP/M, SA-5510 Basic, MS-Basic etc. Adding this device driver +// prepares the ground to add the SOM GPU as the Video emulation of +// the Sharp machines. +// Mar 2023 - v1.4 With the advent of the PCW-8XXX series, seperated distinct machine +// configurations into device driver modules, which are only built +// 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. // // // Notes: See Makefile to enable/disable conditional components @@ -526,6 +527,8 @@ static zuint8 z80_read(void *context, zuint16 address) Z80Ctrl->keyportTrigger = 0; } } + #elif (TARGET_HOST_MZ2000 == 1) + #endif #if(DEBUG_ENABLED & 1) @@ -807,6 +810,31 @@ static zuint8 z80_in(void *context, zuint16 port) // Finally ensure the data from the port is ready and retrieve it. while(CPLD_READY() == 0); value = z80io_PRL_Read(); + + #if (TARGET_HOST_MZ2000 == 1) + // Keyport data? Store. + if((port&0xff) == 0xEA) + { + // If this is the CTRL key row, check the CTRL key. + if((Z80Ctrl->keyportStrobe & 0x1f) == 0x1b) + { + Z80Ctrl->keyportShiftCtrl = (value & 0x08) == 0 ? 0x01 : 0x00; + if(Z80Ctrl->keyportShiftCtrl == 1) + { + Z80Ctrl->keyportTrigger = 0; + } + } else + // If CTRL key is held and we scan the Function Key Row (not all keys mode), then action the pressed key. + if(Z80Ctrl->keyportShiftCtrl == 1 && (Z80Ctrl->keyportStrobe & 0x1f) == 0x10 && (value&0x0f) != 0x0f) + { + Z80Ctrl->keyportHotKey = (value & 0x01) == 0 ? HOTKEY_ORIGINAL : + // (value & 0x02) == 0 ? HOTKEY_RFS40 : + // (value & 0x04) == 0 ? HOTKEY_TZFS : + (value & 0x08) == 0 ? HOTKEY_LINUX : 0x00; + Z80Ctrl->keyportTrigger = Z80Ctrl->keyportHotKey; + } + } + #endif } else // Virtual I/O Port. if(isVirtualIO(port)) @@ -854,6 +882,14 @@ static void z80_out(void *context, zuint16 port, zuint8 value) // Decode address to action any host specific memory map changes. decodeMemoryMapSetup(port, value, 1, false); #endif + + #if (TARGET_HOST_MZ2000 == 1) + // To detect Hotkey presses, we need to store the keyboard strobe data and on keydata read. + if((port&0xff) == 0xE8) + { + Z80Ctrl->keyportStrobe = value; + } + #endif } else if(isVirtualIO(port)) { @@ -1007,39 +1043,38 @@ int thread_z80(void * thread_nr) // Reset pressed? if(CPLD_RESET()) { - resetZ80(); - // Wait for release before restarting CPU. while(CPLD_RESET()); - } else - { - // Update state to indicate request has been actioned. - mutex_lock(&Z80RunModeMutex); - if(Z80RunMode == Z80_STOP) Z80RunMode = Z80_STOPPED; - if(Z80RunMode == Z80_PAUSE) Z80RunMode = Z80_PAUSED; - if(Z80RunMode == Z80_CONTINUE) Z80RunMode = Z80_RUNNING; - if(Z80RunMode == Z80_RUNNING) canRun=1; else canRun=0; - mutex_unlock(&Z80RunModeMutex); - #if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) - // Hotkey pressed? Bring up user menu. - if(Z80Ctrl->keyportTrigger != 0x00 && Z80Ctrl->keyportTriggerLast == 0) - { - z80menu(); - - // Send signal to arbiter to change run mode. - sendSignal(Z80Ctrl->arbTask, SIGUSR1); - Z80Ctrl->keyportShiftCtrl = 0; - - // Suspend processing until arbiter sets up new environment. - mutex_lock(&Z80RunModeMutex); - Z80RunMode = Z80_STOPPED; - canRun = 0; - mutex_unlock(&Z80RunModeMutex); - } - Z80Ctrl->keyportTriggerLast = Z80Ctrl->keyportTrigger; - #endif + resetZ80(); } + + // Update state to indicate request has been actioned. + mutex_lock(&Z80RunModeMutex); + if(Z80RunMode == Z80_STOP) Z80RunMode = Z80_STOPPED; + if(Z80RunMode == Z80_PAUSE) Z80RunMode = Z80_PAUSED; + if(Z80RunMode == Z80_CONTINUE) Z80RunMode = Z80_RUNNING; + 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) + // Hotkey pressed? Bring up user menu. + if(Z80Ctrl->keyportTrigger != 0x00 && Z80Ctrl->keyportTriggerLast == 0) + { + z80menu(); + + // Send signal to arbiter to change run mode. + sendSignal(Z80Ctrl->arbTask, SIGUSR1); + Z80Ctrl->keyportShiftCtrl = 0; + + // Suspend processing until arbiter sets up new environment. + mutex_lock(&Z80RunModeMutex); + Z80RunMode = Z80_STOPPED; + canRun = 0; + mutex_unlock(&Z80RunModeMutex); + } + Z80Ctrl->keyportTriggerLast = Z80Ctrl->keyportTrigger; + #endif } // Release spinlock as we are unloading driver. @@ -1388,7 +1423,7 @@ void setupMemory(enum Z80_MEMORY_PROFILE mode) else #endif // tranZPUter operates in all supported Sharp machines. - #if(TARGET_HOST_PCW == 0) + #if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1) if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_TZPU) tzpuSetupMemory(mode); else diff --git a/software/FusionX/src/z80drv/src/z80driver.h b/software/FusionX/src/z80drv/src/z80driver.h index 2c2f3a0cc..e1110d370 100644 --- a/software/FusionX/src/z80drv/src/z80driver.h +++ b/software/FusionX/src/z80drv/src/z80driver.h @@ -12,9 +12,10 @@ // Copyright: (c) 2019-2023 Philip Smart // (c) 1999-2023 Manuel Sainz de Baranda y Goñi // -// History: Oct 2022 - v1.0 Initial write of the z80 kernel driver software. -// Jan 2023 - v1.1 Added MZ-2000/MZ-80A modes. -// Feb 2023 - v1.2 Added RFS virtual driver. +// History: Oct 2022 - v1.0 Initial write of the z80 kernel driver software. +// 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. // // Notes: See Makefile to enable/disable conditional components // @@ -67,7 +68,7 @@ #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" +#define DRIVER_VERSION "v1.4.1" #define DRIVER_VERSION_DATE "Apr 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. @@ -99,11 +100,11 @@ #define IO_TYPE_VIRTUAL_HW 0x40000000 // Hotkeys handled. -#define HOTKEY_ORIGINAL 0xE8 -#define HOTKEY_RFS40 0xE9 -#define HOTKEY_RFS80 0xEA -#define HOTKEY_TZFS 0xEB -#define HOTKEY_LINUX 0xEC +#define HOTKEY_ORIGINAL 0xE0 +#define HOTKEY_RFS40 0xE1 +#define HOTKEY_RFS80 0xE2 +#define HOTKEY_TZFS 0xE3 +#define HOTKEY_LINUX 0xE4 //********************************************************************************************* // Delay periods for the various hosts, which need adding to the primary opcode fetch in @@ -310,7 +311,7 @@ enum Z80_INSTRUCTION_DELAY { #define INSTRUCTION_DELAY_ROM_64MHZ 14 #define INSTRUCTION_DELAY_ROM_128MHZ 7 #define INSTRUCTION_DELAY_ROM_256MHZ 3 - #define INSTRUCTION_DELAY_RAM_2MHZ 425 + #define INSTRUCTION_DELAY_RAM_2MHZ 429 #define INSTRUCTION_DELAY_RAM_4MHZ 210 #define INSTRUCTION_DELAY_RAM_8MHZ 105 #define INSTRUCTION_DELAY_RAM_16MHZ 52 @@ -573,12 +574,12 @@ enum Z80_INSTRUCTION_DELAY { } #define resetZ80() {\ setupMemory(Z80Ctrl->defaultPageMode);\ + z80_instant_reset(&Z80CPU);\ if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_TZPU)\ {\ + Z80RunMode = Z80_STOPPED;\ sendSignal(Z80Ctrl->ioTask, SIGUSR1); \ - udelay(2000);\ }\ - z80_instant_reset(&Z80CPU);\ } #define IO_ADDR_E0 0xE0 diff --git a/software/FusionX/src/z80drv/src/z80vhw_mz2000.c b/software/FusionX/src/z80drv/src/z80vhw_mz2000.c index fb0c51c0d..6d13839b9 100644 --- a/software/FusionX/src/z80drv/src/z80vhw_mz2000.c +++ b/software/FusionX/src/z80drv/src/z80vhw_mz2000.c @@ -51,16 +51,50 @@ #include #include +#include "tzpu.h" + // Device constants. #define RAM_BASE_ADDR 0x00000 // Base address of the 512K RAM. // System ROM's, either use the host machine ROM or preload a ROM image. #define ROM_DIR "/apps/FusionX/host/MZ-2000/ROMS/" -#define ROM_IPL_ORIG_FILENAME ROM_DIR "mz2000_ipl.orig" +#define ROM_IPL_ORIG_FILENAME ROM_DIR "mz2000_ipl_original.rom" +#define ROM_IPL_FUSIONX_FILENAME ROM_DIR "mz2000_ipl_fusionx.rom" +#define ROM_IPL_TZPU_FILENAME ROM_DIR "mz2000_ipl_tzpu.rom" +#define ROM_1Z001M_FILENAME ROM_DIR "1Z001M.rom" // Boot ROM rom load and size definitions. #define ROM_BOOT_LOAD_ADDR 0x000000 -#define ROM_BOOT_SIZE 0x800 +#define ROM_1Z001M_LOAD_ADDR 0x000000 +#define ROM_ORIG_BOOT_SIZE 0x800 +#define ROM_TZPU_BOOT_SIZE 0x1000 +#define ROM_FUSIONX_BOOT_SIZE 0x1000 +#define ROM_1Z001M_BOOT_SIZE 0x10FB + +// Sharp MZ-2000 constants. +#define MBADDR_FDC 0x0D8 // MB8866 IO Region 0D8h - 0DBh +#define MBADDR_FDC_CR MBADDR_FDC + 0x00 // Command Register +#define MBADDR_FDC_STR MBADDR_FDC + 0x00 // Status Register +#define MBADDR_FDC_TR MBADDR_FDC + 0x01 // Track Register +#define MBADDR_FDC_SCR MBADDR_FDC + 0x02 // Sector Register +#define MBADDR_FDC_DR MBADDR_FDC + 0x03 // Data Register +#define MBADDR_FDC_MOTOR MBADDR_FDC + 0x04 // DS[0-3] and Motor control. 4 drives DS= BIT 0 -> Bit 2 = Drive number, 2=1,1=0,0=0 DS0, 2=1,1=0,0=1 DS1 etc + // bit 7 = 1 MOTOR ON LOW (Active) +#define MBADDR_FDC_SIDE MBADDR_FDC + 0x05 // Side select, Bit 0 when set = SIDE SELECT LOW, +#define MBADDR_FDC_DDEN MBADDR_FDC + 0x06 // Double density enable, 0 = double density, 1 = single density disks. +#define MBADDR_PPIA 0x0E0 // 8255 Port A +#define MBADDR_PPIB 0x0E1 // 8255 Port B +#define MBADDR_PPIC 0x0E2 // 8255 Port C +#define MBADDR_PPICTL 0x0E3 // 8255 Control Port +#define MBADDR_PIOA 0x0E8 // Z80 PIO Port A +#define MBADDR_PIOCTLA 0x0E9 // Z80 PIO Port A Control Port +#define MBADDR_PIOB 0x0EA // Z80 PIO Port B +#define MBADDR_PIOCTLB 0x0EB // Z80 PIO Port B Control Port +#define MBADDR_CRTBKCOLR 0x0F4 // Configure external CRT background colour. +#define MBADDR_CRTGRPHPRIO 0x0F5 // Graphics priority register, character or a graphics colour has front display priority. +#define MBADDR_CRTGRPHSEL 0x0F6 // Graphics output select on CRT or external CRT +#define MBADDR_GRAMCOLRSEL 0x0F7 // Graphics RAM colour bank select. +#define MBADDR_GRAMADDRL 0x0C000 // Graphics RAM base address. // PCW control. typedef struct { @@ -84,9 +118,6 @@ void mz2000SetupMemory(enum Z80_MEMORY_PROFILE mode) // Locals. uint32_t idx; - // The PCW contains upto 512KB of standard RAM which can be expnded to a physical max of 2MB. The kernel malloc limit is 2MB so the whole virtual - // memory can be mapped into the PCW memory address range. - // Setup defaults. MZ2000Ctrl.lowMemorySwap = 0x01; // Set memory swap flag to swapped, ie. IPL mode sees DRAM 0x0000:0x7FFF swapped to 0x8000:0xFFFF and ROM pages into 0x0000. MZ2000Ctrl.highMemoryVRAM = 0x00; @@ -148,12 +179,22 @@ void mz2000SetupMemory(enum Z80_MEMORY_PROFILE mode) Z80Ctrl->refreshDRAM = 2; } + // tranZPUter I/O Ports need to be declared virtual to process locally. + for(idx=0x0000; idx < IO_PAGE_SIZE; idx+=0x0100) + { + Z80Ctrl->iopage[idx+IO_TZ_SVCREQ] = IO_TZ_SVCREQ | IO_TYPE_VIRTUAL_HW; + Z80Ctrl->iopage[idx+IO_TZ_SYSREQ] = IO_TZ_SYSREQ | IO_TYPE_VIRTUAL_HW; + } + + // Ensure 40 char mode is enabled. +// SPI_SEND_32(MBADDR_PIOA, 0x13); + pr_info("MZ-2000 Memory Setup complete.\n"); } // Method to load a ROM image into the RAM memory. // -uint8_t mz2000LoadROM(const char* romFileName, uint32_t loadAddr, uint32_t loadSize) +uint8_t mz2000LoadROM(const char* romFileName, uint8_t useROM, uint32_t loadAddr, uint32_t loadSize) { // Locals. uint8_t result = 0; @@ -168,10 +209,10 @@ uint8_t mz2000LoadROM(const char* romFileName, uint32_t loadAddr, uint32_t loadS } else { vfs_llseek(fp, 0, SEEK_SET); - noBytes = kernel_read(fp, fp->f_pos, &Z80Ctrl->ram[loadAddr], loadSize); + noBytes = kernel_read(fp, fp->f_pos, useROM == 1 ? &Z80Ctrl->rom[loadAddr] : &Z80Ctrl->ram[loadAddr], loadSize); if(noBytes < loadSize) { - pr_info("Short load, ROM Image:%s, bytes loaded:%08x\n:", romFileName, loadSize); + pr_info("Short load, Image:%s, bytes loaded:%08x\n:", romFileName, loadSize); } filp_close(fp,NULL); } @@ -185,6 +226,35 @@ void mz2000Init(uint8_t mode) // Locals. uint32_t idx; +// // Initialise the Z80 PIO/8255 controllers. +// // +// SPI_SEND_32(MBADDR_PPICTL, 0x82); // 8255 A=OUT B=IN C=OUT +// SPI_SEND_32(MBADDR_PPIC, 0x58); // BST=1 NST=0 OPEN=1 WRITE=1 +// SPI_SEND_32(MBADDR_PPIA, 0xF7); // All signals inactive, stop cassette. +// SPI_SEND_32(MBADDR_PIOCTLA, 0x0F); // Setup PIO A +// SPI_SEND_32(MBADDR_PIOCTLB, 0xCF); // Setup PIO B +// SPI_SEND_32(MBADDR_PIOCTLB, 0xFF); +// +// // Initialise video hardware. +// // +// SPI_SEND_32(MBADDR_CRTGRPHSEL, 0x00); // Set Graphics VRAM to default, no access to GRAM. +// SPI_SEND_32(MBADDR_CRTBKCOLR, 0x00); // Set background colour on external output to black. +// SPI_SEND_32(MBADDR_GRAMCOLRSEL, 0x01); // Activate Blue graphics RAM bank for graphics operations (this is the default installed bank, red and green are optional). +// SPI_SEND_32(MBADDR_CRTGRPHPRIO, 0x07); // Enable all colour bank graphic output with character priority. +// SPI_SEND_32(MBADDR_PIOA, 0x13); // A7 : H 0xD000:0xD7FF or 0xC000:0xFFFF VRAN paged in. +// // A6 : H Select Character VRAM (H) or Graphics VRAM (L) +// // A5 : H Select 80 char mode, 40 char mode = L +// // A4 : L Select all key strobe lines active, for detection of any key press. +// // A3-A0: Keyboard strobe lines +// SPI_SEND_32(MBADDR_PPIA, 0xFF); // A7 : L APSS Search for next program +// // A6 : L Automatic playback at end of rewind +// // A5 : L Automatic rewind during playback(recording) +// // A4 : L Invert Video +// // A3 : L Stop Cassette +// // A2 : L Play Cassette +// // A1 : L Fast Forward +// // A0 : L Rewind + // 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. @@ -226,8 +296,11 @@ void mz2000Init(uint8_t mode) // Initial memory config. mz2000SetupMemory(Z80Ctrl->defaultPageMode); - - // mz2000LoadROM(ROM_IPL_ORIG_FILENAME, ROM_BOOT_LOAD_ADDR, ROM_BOOT_SIZE); + + // Overwrite the ROM with a modified version (comment out) if needed. + //mz2000LoadROM(ROM_IPL_ORIG_FILENAME, ROM_BOOT_LOAD_ADDR, ROM_ORIG_BOOT_SIZE); + //mz2000LoadROM(ROM_IPL_TZPU_FILENAME, ROM_BOOT_LOAD_ADDR, ROM_TZPU_BOOT_SIZE); + mz2000LoadROM(ROM_IPL_FUSIONX_FILENAME, 1, ROM_BOOT_LOAD_ADDR, ROM_FUSIONX_BOOT_SIZE); pr_info("Enabling MZ-2000 driver.\n"); return; @@ -299,6 +372,7 @@ static inline void mz2000DecodeMemoryMapSetup(zuint16 address, zuint8 data, uint // NST pages in all RAM and resets cpu. if(data & 0x01) { +pr_info("NST Reset\n"); MZ2000Ctrl.lowMemorySwap = 0; for(idx=0x0000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY) { @@ -320,6 +394,7 @@ static inline void mz2000DecodeMemoryMapSetup(zuint16 address, zuint8 data, uint // If IPL is active (L), reconfigure memory for power on state. if((data & 0x01) == 0) { +pr_info("IPL Reset\n"); mz2000SetupMemory(Z80Ctrl->defaultPageMode); } break; @@ -415,9 +490,28 @@ static inline void mz2000Write(zuint16 address, zuint8 data, uint8_t ioFlag) // I/O Operation? if(ioFlag) { - switch(address) + // Only the lower 8 bits of the I/O address are processed as the upper byte is not used in the Sharp models. + // + switch(address & 0x00FF) { + case IO_TZ_SVCREQ: + #if(DEBUG_ENABLED & 0x01) + if(Z80Ctrl->debug >= 3) pr_info("SVCREQ:%02x\n", data); + #endif + + // If a k64f process has registered, send it a service request signal. +pr_info("Sending signal,%02x\n", data); + sendSignal(Z80Ctrl->ioTask, SIGIO); + break; + + case IO_TZ_SYSREQ: + #if(DEBUG_ENABLED & 0x01) + if(Z80Ctrl->debug >= 3) pr_info("SYSREQ:%02x\n", data); + #endif + break; + default: + pr_info("PORT:%02x\n", data); break; } } else diff --git a/software/FusionX/src/z80drv/src/z80vhw_mz700.c b/software/FusionX/src/z80drv/src/z80vhw_mz700.c index de229b19f..82e385cd9 100644 --- a/software/FusionX/src/z80drv/src/z80vhw_mz700.c +++ b/software/FusionX/src/z80drv/src/z80vhw_mz700.c @@ -74,9 +74,6 @@ void mz700SetupMemory(enum Z80_MEMORY_PROFILE mode) // Locals. uint32_t idx; - // The PCW contains upto 512KB of standard RAM which can be expnded to a physical max of 2MB. The kernel malloc limit is 2MB so the whole virtual - // memory can be mapped into the PCW memory address range. - // Setup defaults. MZ700Ctrl.regCtrl = 0x00; @@ -196,6 +193,9 @@ void mz700Init(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. @@ -230,29 +230,27 @@ void mz700Init(uint8_t mode) } } - // Add in a test program to guage execution speed. - #if(TARGET_HOST_MZ700 == 1) - Z80Ctrl->ram[0x1200] = 0x01; - Z80Ctrl->ram[0x1201] = 0x86; - Z80Ctrl->ram[0x1202] = 0xf2; - Z80Ctrl->ram[0x1203] = 0x3e; - Z80Ctrl->ram[0x1204] = 0x15; - Z80Ctrl->ram[0x1205] = 0x3d; - Z80Ctrl->ram[0x1206] = 0x20; - Z80Ctrl->ram[0x1207] = 0xfd; - Z80Ctrl->ram[0x1208] = 0x0b; - Z80Ctrl->ram[0x1209] = 0x78; - Z80Ctrl->ram[0x120a] = 0xb1; - Z80Ctrl->ram[0x120b] = 0x20; - Z80Ctrl->ram[0x120c] = 0xf6; - Z80Ctrl->ram[0x120d] = 0xc3; - Z80Ctrl->ram[0x120e] = 0x00; - Z80Ctrl->ram[0x120f] = 0x00; - #endif - - // Reset memory paging to default. - SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR); + // Initial memory config. + mz700SetupMemory(Z80Ctrl->defaultPageMode); + // Add in a test program to guage execution speed. + Z80Ctrl->ram[0x1200] = 0x01; + Z80Ctrl->ram[0x1201] = 0x86; + Z80Ctrl->ram[0x1202] = 0xf2; + Z80Ctrl->ram[0x1203] = 0x3e; + Z80Ctrl->ram[0x1204] = 0x15; + Z80Ctrl->ram[0x1205] = 0x3d; + Z80Ctrl->ram[0x1206] = 0x20; + Z80Ctrl->ram[0x1207] = 0xfd; + Z80Ctrl->ram[0x1208] = 0x0b; + Z80Ctrl->ram[0x1209] = 0x78; + Z80Ctrl->ram[0x120a] = 0xb1; + Z80Ctrl->ram[0x120b] = 0x20; + Z80Ctrl->ram[0x120c] = 0xf6; + Z80Ctrl->ram[0x120d] = 0xc3; + Z80Ctrl->ram[0x120e] = 0x00; + Z80Ctrl->ram[0x120f] = 0x00; + pr_info("Enabling MZ-700 driver.\n"); return; } diff --git a/software/FusionX/src/z80drv/src/z80vhw_pcw.c b/software/FusionX/src/z80drv/src/z80vhw_pcw.c index d10117d4b..1f5c98863 100644 --- a/software/FusionX/src/z80drv/src/z80vhw_pcw.c +++ b/software/FusionX/src/z80drv/src/z80vhw_pcw.c @@ -194,6 +194,9 @@ void pcwInit(uint8_t mode) Z80Ctrl->ram[0] = 0x00; Z80Ctrl->ram[1] = 0x00; + // Initial memory config. + pcwSetupMemory(Z80Ctrl->defaultPageMode); + pr_info("Enabling PCW-%s driver.\n", mode == 0 ? "8256" : "9256"); return; } @@ -297,7 +300,7 @@ pr_info("VORIGIN:%02x\n", data); pr_info("SCREENATTR:%02x\n", data); break; case IO_GACMD: -pr_info("GACMD:%02x\n", data); +//pr_info("GACMD:%02x\n", data); break; default: diff --git a/software/FusionX/src/z80drv/src/z80vhw_tzpu.c b/software/FusionX/src/z80drv/src/z80vhw_tzpu.c index 2b4a69111..490220d64 100644 --- a/software/FusionX/src/z80drv/src/z80vhw_tzpu.c +++ b/software/FusionX/src/z80drv/src/z80vhw_tzpu.c @@ -150,7 +150,7 @@ void tzpuSetupMemory(enum Z80_MEMORY_PROFILE mode) TZPUCtrl.regCpldCfg = 0x00; // Not used, as no CPLD available, but need to store/return value if addressed. // Default memory mode, TZFS. - Z80Ctrl->memoryMode = TZMM_ORIG; + Z80Ctrl->memoryMode = TZMM_TZFS; // Reset IO mapping. for(idx=0x0000; idx < IO_PAGE_SIZE; idx++)