פרק 5: מערכת ההפעלה Commodore-64 בשפת Assembly

Prq 5 M Rkt Hhp Lh Commodore 64 Bspt Assembly



5.1 מבוא

מערכת ההפעלה למחשב Commodore-64 מגיעה עם המחשב בזיכרון קריאה בלבד (ROM). מספר מיקומי בייט הזיכרון עבור ה-Commodore-64 נע בין $0000 ל-$FFFF (כלומר 000016 עד FFFF16 שהם 010 עד 65,53510). מערכת ההפעלה היא מ-$E000 ל-$FFFF (כלומר 57,34410 עד 65,53610).

למה ללמוד את מערכת ההפעלה Commodore-64
למה ללמוד את מערכת ההפעלה Commodore-64 היום כשהיא הייתה מערכת הפעלה של מחשב שיצאה בשנת 1982? ובכן, מחשב Commodore-64 משתמש ביחידת העיבוד המרכזית 6510 שהיא שדרוג (אם כי לא שדרוג גדול) של ה-6502 µP.







ה-6502 µP עדיין מיוצר היום במספרים גדולים; זה כבר לא עבור מחשבים ביתיים או משרדיים אלא עבור מכשירים חשמליים ואלקטרוניים (מכשירים). ה-6502 µP הוא גם פשוט להבנה ולתפעול בהשוואה לשאר המיקרו-מעבדים של ימיו. כתוצאה מכך, זהו אחד המיקרו-מעבדים הטובים ביותר (אם לא הטובים ביותר) המשמשים ללמד את שפת ה-Assembly.



ל-65C02 µP, עדיין מקבוצת המיקרו-מעבדים 6502, יש 66 הוראות שפת assembly, שאת כולן ניתן אפילו ללמוד בעל פה. למיקרו-מעבדים מודרניים יש הרבה הוראות שפת assembly ולא ניתן ללמוד אותם בעל פה. לכל µP יש שפת הרכבה משלו. כל מערכת הפעלה, חדשה או ישנה, ​​היא של שפת assembly. עם זה, שפת ההרכבה 6502 טובה לשימוש כדי ללמד את מערכת ההפעלה למתחילים. לאחר לימוד מערכת הפעלה, כמו זו של Commodore-64, ניתן ללמוד בקלות מערכת הפעלה מודרנית תוך שימוש בה כבסיס.



זו לא רק דעתו של המחבר (עצמי). זוהי מגמה גוברת בעולם. יותר ויותר מאמרים נכתבים באינטרנט עבור מערכת הפעלה משופרת Commodore-64 כדי שתראה כמו מערכת הפעלה מודרנית. מערכות הפעלה מודרניות מוסברות בפרק שלאחר הפרק הבא.





הערה : מערכת ההפעלה Commodore-64 (Kernal) עדיין עובדת היטב עם התקני קלט ופלט מודרניים (לא כולם).

מחשב שמונה סיביות
במיקרו-מחשב של שמונה סיביות כגון קומודור 64, המידע מאוחסן, מועבר ומתופעל בצורה של קודים בינאריים של שמונה סיביות.



מפת זיכרון
מפת זיכרון היא קנה מידה אשר מחלק את טווח הזיכרון המלא לטווחים קטנים יותר בגדלים שונים ומראה מה (תת שגרה ו/או משתנה) שייך לאיזה טווח. משתנה הוא תווית המתאימה לכתובת זיכרון מסוימת שיש לה ערך. תוויות משמשות גם לזיהוי תחילתן של תתי שגרות. אבל במקרה זה, הם ידועים בתור השמות של תת-השגרה. אפשר פשוט להתייחס לתת-שגרה כשגרה.

מפת הזיכרון (פריסה) בפרק הקודם אינה מפורטת מספיק. זה די פשוט. ניתן להציג את מפת הזיכרון של מחשב Commodore-64 עם שלוש רמות של פרטים. כאשר מוצג ברמת הביניים, למחשב Commodore-64 יש מפות זיכרון שונות. מפת הזיכרון המוגדרת כברירת מחדל של מחשב Commodore-64 ברמת הביניים היא:


איור 5.11 מפת זיכרון Commodore-64

באותם ימים הייתה שפת מחשב פופולרית בשם BASIC. משתמשי מחשב רבים היו צריכים לדעת כמה פקודות שפה בסיסיות מינימליות כגון טעינת תוכנית מהדיסק (דיסק) לזיכרון, להפעיל (להפעיל) תוכנית בזיכרון ולצאת (לסגור) תוכנית. כאשר תוכנית BASIC פועלת, המשתמש צריך להזין את הנתונים, שורה אחר שורה. זה לא כמו היום כאשר אפליקציה (מספר תוכנות יוצרות אפליקציה) כתובה בשפה ברמה גבוהה עם חלונות והמשתמש רק צריך להתאים את הנתונים השונים במקומות מיוחדים בחלון. במקרים מסוימים, השתמש בעכבר כדי לבחור את הנתונים שהוזמנו מראש. BASIC הייתה שפה ברמה גבוהה באותה תקופה, אבל די קרובה לשפת האסמבלי.

שימו לב שרוב הזיכרון נתפס על ידי BASIC במפת הזיכרון המוגדרת כברירת מחדל. ל-BASIC יש פקודות (הוראות) אשר מבוצעות על ידי מה שידוע כ-BASIC Interpreter. למעשה, המתורגמן BASIC נמצא ב-ROM ממיקום $A000 ועד $BFFF (כולל) שהוא כביכול אזור RAM. זה 8 Kbytes הוא די גדול באותו זמן! זה למעשה נמצא ב-ROM באותו מקום של כל הזיכרון. יש לו גודל זהה למערכת ההפעלה מ-$E000 עד $FFFF (כולל). התוכניות שנכתבות ב-BASIC ממוקמות גם הן בטווח של $0200 עד $BFFF.

זיכרון ה-RAM עבור תוכנית שפת ההרכבה של המשתמש הוא מ-$C000 ל-$CFFF, רק 4 Kbytes מתוך 64 Kbytes. אז, למה אנחנו משתמשים או לומדים את שפת ה-Assembly? מערכות ההפעלה החדשות והישנות הן של שפות assembly. מערכת ההפעלה של ה-Commodore-64 היא ב-ROM, מ-$E000 ל-$FFFF. הוא כתוב בשפת ההרכבה 65C02 µP (6510 µP). זה מורכב מתתי שגרות. תוכנית המשתמש בשפת assembly צריכה לקרוא לתתי השגרות הללו כדי ליצור אינטראקציה עם ציוד היקפי (התקני קלט ופלט). הבנת מערכת ההפעלה Commodore-64 בשפת assembly מאפשרת לתלמיד להבין את מערכות ההפעלה במהירות, בצורה הרבה פחות מייגעת. שוב, באותם ימים, תוכניות משתמש רבות עבור Commodore-64 נכתבו ב-BASIC ולא בשפת assembly. שפות ההרכבה באותם ימים שימשו יותר את המתכנתים עצמם למטרות טכניות.

ה-Kernal, מאוית כ-K-e-r-n-a-l, היא מערכת ההפעלה של ה-Commodore-64. הוא מגיע עם מחשב Commodore-64 ב-ROM ולא בדיסק (או דיסקט). הקרנל מורכב מתתי שגרות. על מנת לגשת לציוד ההיקפי, על תוכנית המשתמש בשפת assembly (שפת מכונה) להשתמש בתתי השגרות הללו. אין לבלבל את ה-Kernal עם הליבה שנכתבת כ-K-e-r-n-e-l של מערכות ההפעלה המודרניות, למרות שהן כמעט אותו הדבר.

אזור הזיכרון מ-$C000 (49,15210) ל-$CFFF (6324810) של 4 Kbytes10 מהזיכרון הוא RAM או ROM. כאשר מדובר ב-RAM, הוא משמש לגישה לציוד ההיקפי. כאשר זה ROM, הוא משמש להדפסת התווים על המסך (צג). המשמעות היא שאו שהתווים מודפסים על המסך או שהגישה לציוד ההיקפי מתבצע על ידי שימוש בחלק זה של הזיכרון. יש בנק של ROM (ROM של תווים) ביחידת המערכת (לוח האם) שמועבר פנימה והחוצה מכל שטח הזיכרון כדי להשיג זאת. ייתכן שהמשתמש לא יבחין במעבר.

אזור הזיכרון מ-$0100 (256 10 ) ל-$01FF (511 10 ) הוא הערימה. הוא משמש גם את מערכת ההפעלה וגם את תוכניות המשתמש. תפקיד המחסנית הוסבר בפרק הקודם של קורס קריירה מקוון זה. שטח הזיכרון מ-$0000 (0 10 ) עד $00FF (255 10 ) משמש את מערכת ההפעלה. מצביעים רבים מוקצים לשם.

Kernal Jump Table
ל-Kernal יש שגרות שנקראות על ידי תוכנית המשתמש. ככל שיצאו גרסאות חדשות של מערכת ההפעלה, הכתובות של השגרות הללו השתנו. המשמעות היא שתוכניות המשתמש לא יכלו עוד לעבוד עם גרסאות מערכת ההפעלה החדשות. זה לא קרה כי קומודור-64 סיפק טבלת קפיצות. טבלת הקפיצות היא רשימה של 39 ערכים. לכל ערך בטבלה שלוש כתובות (פרט ל-6 הבתים האחרונים) שמעולם לא השתנו אפילו עם שינוי הגרסה של מערכת ההפעלה.

הכתובת הראשונה של ערך כוללת הוראה JSR. שתי הכתובות הבאות מורכבות ממצביע של שני בתים. מצביע זה של שני בתים הוא הכתובת (או הכתובת החדשה) של שגרה בפועל שעדיין נמצאת ב-OS ROM. תוכן המצביע עשוי להשתנות עם גרסאות מערכת ההפעלה החדשות, אך שלוש הכתובות עבור כל כניסה בטבלת קפיצה לעולם לא משתנות. לדוגמה, שקול את הכתובות $FF81, $FF82 ו-$FF83. שלוש הכתובות הללו מיועדות לשגרה לאתחל את מעגלי המסך והמקלדת (אוגרים) של לוח האם. לכתובת $FF81 תמיד יש את קוד הפעולה (בייט אחד) של JSR. לכתובות $FF82 ו-$FF83 יש את הכתובת הישנה או החדשה של תת-השגרה (עדיין ב-OS ROM) כדי לבצע את האתחול. פעם אחת, הכתובות $FF82 ו-$FF83 היו עם התוכן (הכתובת) של $FF5B שיכול להשתנות עם גרסת מערכת ההפעלה הבאה. עם זאת, הכתובות $FF81, $FF82 ו-$FF83 של טבלת הקפיצות לעולם לא משתנות.

עבור כל הזנה של שלוש כתובות, הכתובת הראשונה עם JSR כוללת תווית (שם). התווית עבור $FF81 היא PCINT. PCINT אף פעם לא משתנה. לכן, כדי לאתחל את אוגרי המסך והמקלדת, המתכנת יכול פשוט להקליד 'JSR PCINT' שעובד עבור כל הגרסאות של מערכת ההפעלה Commodore-64. המיקום (כתובת ההתחלה) של תת-השגרה בפועל, למשל, $FF5B, עשוי להשתנות עם הזמן עם מערכות הפעלה שונות. כן, יש לפחות שתי הוראות JSR המעורבות בתוכנת המשתמש שמשתמשת במערכת ההפעלה ROM. בתוכנת המשתמש ישנה הוראת JSR שקופצת לערך בטבלת הקפיצה. למעט שש הכתובות האחרונות בטבלת הקפיצה, הכתובת הראשונה של ערך בטבלת הקפיצה כוללת הוראה JSR. ב-Kernal, חלק מתת-השגרה יכולה לקרוא ליתר-השגרה.

טבלת הקפיצה של Kernal מתחילה מ-$FF81 (כולל) עולה בקבוצות של שלשות, למעט ששת הבתים האחרונים שהם שלושה מצביעים עם כתובות בתים נמוכות יותר: $FFFA, $FFFC ו-$FFFE. כל השגרות של מערכת ההפעלה ROM הן קודים לשימוש חוזר. לכן, המשתמש לא צריך לשכתב אותם.

תרשים בלוקים של יחידת מערכת קומודור-64
התרשים הבא מפורט יותר מזה שבפרק הקודם:


איור 5.12 תרשים בלוקים של יחידת המערכת Commodore_64

ROM ו-RAM מוצגים כאן כגוש אחד. שבב ממשק הווידאו (IC) לטיפול במידע למסך, שלא הוצג בפרק הקודם, מוצג כאן. הבלוק היחיד עבור התקני קלט/פלט, שמוצג בפרק הקודם, מוצג כאן כשני בלוקים: CIA #1 ו-CIA #2. CIA ראשי תיבות של Complex Interface Adapter. לכל אחת יש שתי יציאות מקבילות של שמונה סיביות (לא להתבלבל עם יציאות חיצוניות על משטח אנכי של יחידת המערכת) הנקראות יציאה A ויציאה B. ה-CIA מחוברים לחמישה התקנים חיצוניים במצב זה. ההתקנים הם המקלדת, הג'ויסטיק, כונן הדיסקים/מדפסת, ומודם. המדפסת מחוברת בחלק האחורי של כונן הדיסקים. יש גם מעגל התקן ממשק קול ומעגל מערך לוגי שניתן לתכנות שאינם מוצגים.

ובכל זאת, יש ROM של Character שניתן להחליף עם שני ה-CIA כאשר תו נשלח למסך והוא אינו מוצג בתרשים הבלוק.

כתובות ה-RAM מ-$D000 ל-$DFFF עבור מעגלי קלט/פלט בהיעדר ROM של תווים כוללות את מפת הזיכרון המפורטת הבאה:

טבלה 5.11
מפת זיכרון מפורטת מ-$D000 ל-$DFFF
טווח כתובות משנה מעגל חשמלי גודל (בייט)
D000 – D3FF VIC (בקר ממשק וידאו (שבב)) 1K
D400 – D7FF SID (מעגל קול) 1K
D800 – DBFF זיכרון RAM צבעוני 1K ניבלים
DC00 – DCFF CIA #1 (מקלדת, ג'ויסטיק) 256
DD00 – DDFF CIA #2 (אוטובוס טורי, יציאת משתמש/RS-232) 256
DE00 – DEF פתח את חריץ I/O #1 256
DF00 – DFFF פתח את חריץ I/O #2 256

5.2 שני מתאמי הממשק המורכבים

ישנם שני מעגלים משולבים (ICs) מסוימים ביחידת המערכת Commodore-64, וכל אחד מהם נקרא מתאם ממשק מורכב. שני השבבים הללו משמשים לממשק המקלדת וציוד היקפי אחר למיקרו-מעבד. למעט ה-VIC והמסך, כל אותות הקלט/פלט בין המיקרו-מעבד והציוד ההיקפי עוברים דרך שני ה-ICs הללו. עם ה-Commodore-64, אין תקשורת ישירה בין הזיכרון לציוד היקפי כלשהו. התקשורת בין הזיכרון לכל ציוד היקפי עוברת דרך מצבר המיקרו-מעבד, ואחד מהם הוא מתאמי CIA (ICs). ה-ICs מכונים CIA #1 ו-CIA #2. CIA ראשי תיבות של Complex Interface Adapter.

לכל CIA יש 16 אוגרים. למעט אוגרי הטיימר/מונה ב-CIA, כל אוגר הוא ברוחב של 8 סיביות ויש לו כתובת זיכרון. כתובות אוגר הזיכרון עבור CIA #1 הן מ-$DC00 (56320 10 ) ל-$DC0F (56335 10 ). כתובות אוגר הזיכרון עבור CIA #2 הן מ-$DD00 (56576 10 ) ל-$DD0F (56591 10 ). אף על פי שהאוגרים הללו אינם בזיכרון ה-IC, הם חלק מהזיכרון. במפת הזיכרון הביניים, אזור ה-I/O מ-$D000 ל-$DFFF כולל את כתובות ה-CIA מ-$DC00 ל-$DC0F ומ-$DD00 ל-$DD0F. ניתן להחליף את רוב אזור הזיכרון I/O של RAM מ-$D000 ל-$DFFF עם בנק הזיכרון של ROM התווים לתווי מסך. זו הסיבה שכאשר הדמויות נשלחות למסך, הציוד ההיקפי אינו יכול לפעול; אם כי ייתכן שהמשתמש לא שם לב לכך מכיוון שההחלפה הלוך ושוב היא מהירה.

ישנם שני אוגרים ב-CIA #1 הנקראים Port A ו- Port B. הכתובות שלהם הן $DC00 ו-$DC01, בהתאמה. ישנם גם שני אוגרים ב-CIA #2 הנקראים Port A ו- Port B. כמובן, הכתובות שלהם שונות; הם $DD00 ו-$DD01, בהתאמה.

יציאה A או יציאה B בכל אחד מה-CIA היא יציאה מקבילה. זה אומר שהוא יכול לשלוח את הנתונים לציוד ההיקפי בשמונה סיביות בבת אחת או לקבל את הנתונים מהמיקרו-מעבד בשמונה סיביות בבת אחת.

עם יציאה A או יציאה B משויך Registr Data Direction (DDR). אוגר כיוון הנתונים עבור יציאה A של CIA #1 (DDRA1) נמצא במיקום בייט הזיכרון של $DC02. אוגר כיוון הנתונים עבור יציאה B של CIA #1 (DDRB1) נמצא במיקום בייט הזיכרון של $DC03. אוגר כיוון הנתונים עבור יציאה A של CIA #2 (DDRA2) נמצא במיקום בייט הזיכרון של $DD02. אוגר כיוון הנתונים עבור יציאה B של CIA #2 (DDRB2) נמצא במיקום בייט הזיכרון של $DD03.

כעת, כל סיביות עבור יציאה A או יציאה B יכולה להיות מוגדרת על ידי אוגר כיוון הנתונים המתאים להיות הקלט או הפלט. קלט אומר שהמידע עובר מהציוד ההיקפי למיקרו-מעבד דרך CIA. פלט פירושו שהמידע עובר מהמיקרו-מעבד אל הציוד ההיקפי דרך CIA.

אם יש להזין תא של יציאה (אוגר), הסיבית המקבילה באוגר כיוון הנתונים הוא 0. אם יש להוציא תא של יציאה (אוגר), הסיבית המקבילה באוגר כיוון הנתונים הוא 1. ברוב המקרים, כל 8 סיביות של יציאה מתוכנתות להיות קלט או פלט. כאשר המחשב מופעל, יציאה A מתוכנתת לפלט ויציאה B מתוכנתת לקלט. הקוד הבא הופך את יציאת CIA #1 כפלט ואת יציאת CIA #1 B כקלט:

LDA #$FF
STA DDRA1 ; $DC00 מבוים על ידי $DC02
LDA #$00
STA DDRB1 ; $DC01 מבוים על ידי $DC03

DDRA1 הוא התווית (שם המשתנה) עבור מיקום בת הזיכרון של $DC02, ו-DDRB1 הוא התווית (שם המשתנה) עבור מיקום בת הזיכרון של $DC03. ההוראה הראשונה טוענת 11111111 לצובר של µP. ההוראה השנייה מעתיקה זאת למאגר כיוון הנתונים של יציאה A של מס' ה-CIA. 1. ההוראה השלישית טוענת 00000000 לצובר של µP. ההוראה הרביעית מעתיקה זאת למאגר כיוון הנתונים של יציאה B של CIA מס. 1. הקוד הזה נמצא באחת מתתי השגרות במערכת ההפעלה שעושה את האתחול הזה עם הפעלת המחשב.

לכל CIA יש קו בקשת שירות פסיקה למיקרו-מעבד. זה מה-CIA #1 הולך ל- IRQ סיכה של µP. זה מ-CIA #2 הולך ל- NMI סיכה של µP. זכור את זה NMI הוא בעדיפות גבוהה יותר מאשר IRQ .

5.3 תכנות שפת מקלדת

יש רק שלוש פסיקות אפשריות עבור ה-Commodore-64: IRQ , BRK, ו NMI . מצביע שולחן הקפיצה עבור IRQ נמצא בכתובות $FFFE ו-$FFFF ב-ROM (מערכת הפעלה) התואמת תת-שגרה שעדיין נמצאת במערכת ההפעלה (ROM). מצביע הטבלה לקפיצה עבור BRK נמצא בכתובות $FFFC ו-$FFFD במערכת ההפעלה, התואמת לשגרת משנה שעדיין נמצאת במערכת ההפעלה (ROM). מצביע שולחן הקפיצה עבור NMI נמצא בכתובות $FFFA ו-$FFFB במערכת ההפעלה, התואמת לשגרת משנה שעדיין נמצאת במערכת ההפעלה (ROM). בשביל ה IRQ , יש למעשה שתי תתי שגרות. אז, לפסיקת תוכנת BRK (הוראה) יש מצביע טבלת קפיצה משלה. מצביע שולחן הקפיצה עבור IRQ מוביל לקוד שמחליט אם מדובר בפסיקת החומרה או בפסיקת התוכנה שפועלת. אם זו הפרעה בחומרה, השגרה עבור IRQ נקרא. אם מדובר בפסיקת התוכנה (BRK), השגרה של BRK נקראת. באחת מגרסאות מערכת ההפעלה, תת-השגרה עבור IRQ הוא ב-$EA31 ותת-השגרה עבור BRK היא ב-$FE66. כתובות אלו הן מתחת ל-$FF81, כך שהן אינן ערכי טבלת קפיצה והן עשויות להשתנות עם גרסת מערכת ההפעלה. ישנן שלוש שגרות מעניינות בנושא זה: זו שבודקת אם זה מקש לחוץ או BRK, זו שעומדת על 43$ FE, וזו שעשוי להשתנות גם עם גרסת מערכת ההפעלה.

מחשב Commodore-64 הוא כמו מכונת כתיבה ענקית (למעלה) במראה ללא קטע ההדפסה (ראש ונייר). המקלדת מחוברת ל-CIA #1. ה-CIA #1 סורק את המקלדת כל 1/60 שנייה בעצמו ללא הפרעות תכנות, כברירת מחדל. אז, כל 1/60 של שנייה, ה-CIA #1 שולח א IRQ ל-µP. יש רק אחד IRQ הצמד ב-µP שמגיע רק מ-CIA #1. פין הקלט האחד של NMI של µP, שהוא שונה מ IRQ , מגיע רק מ-CIA #2 (עיין באיור הבא). BRK היא למעשה הוראה בשפת assembly שמקודדת בתוכנת משתמש.

אז, כל 1/60 שנייה, ה IRQ שגרה שעליה מצביעים $FFFE ו-$FFFF נקראת. השגרה בודקת אם מקש נלחץ או נתקלת בהוראת BRK. אם לוחצים על מקש, נקראת השגרה לטיפול בלחיצת המקשים. אם זו הוראת BRK, השגרה לטיפול ב-BRK נקראת. אם זה לא אחד, שום דבר לא קורה. אף אחד מהם לא יכול להתרחש, אבל CIA #1 שולח IRQ ל- µP כל 1/60 שניה.

תור המקלדת, המכונה גם מאגר המקלדת, הוא מגוון של מיקומי בתים של RAM מ-$0277 עד $0280, כולל; 1010 בתים בסך הכל. זהו מאגר First-IN-First-Out. זה אומר שהדמות הראשונה שתגיע היא הראשונה שעוזבת. תו מערב אירופאי לוקח בייט אחד.

לכן, בעוד שהתוכנית אינה צורכת שום תו בעת לחיצה על מקש, קוד המפתח נכנס למאגר הזה (תור). המאגר ממשיך להתמלא עד שיש עשרה תווים. כל תו שנלחץ לאחר התו העשירי אינו מוקלט. מתעלמים ממנו עד שלפחות תו אחד מתקבל (נצרך) מהתור. לטבלת הקפיצה יש ערך לתתי שגרה שמקבלת את התו הראשון מהתור אל המיקרו-מעבד. זה אומר שהוא לוקח את התו הראשון שנכנס לתור ומכניס אותו לצובר של µP. תת-השגרה של טבלת הקפיצה לעשות זאת נקראת GETIN (עבור Get-In). הבית הראשון עבור ערך שלושת הבתים בטבלת הקפיצה מסומן כ-GETIN (כתובת $FFE4). שני הבתים הבאים הם המצביע (הכתובת) שמצביע על השגרה בפועל ב-ROM (OS). באחריות המתכנת לקרוא לשגרה זו. אחרת, מאגר המקלדת יישאר מלא ויתעלמו מכל המקשים שנלחצו לאחרונה. הערך שנכנס למצבר הוא ערך המפתח ASCII המתאים.

איך קודי המפתח נכנסים לתור מלכתחילה? קיימת שגרת קפיצה בטבלה בשם SCNKEY (עבור מפתח סריקה). שגרה זו יכולה להיקרא הן על ידי תוכנה והן על ידי חומרה. במקרה זה, זה נקרא על ידי מעגל אלקטרוניקה (פיזיקה) במיקרו-מעבד כאשר האות החשמלי IRQ נמוך. איך זה נעשה בדיוק לא מתייחסים בקורס קריירה מקוון זה.

הקוד לקבל את קוד המפתח הראשון ממאגר המקלדת לתוך מצבר A הוא רק שורה אחת:

להכנס

אם מאגר המקלדת ריק, 00$ מונח בצובר. זכור שקוד ה-ASCII עבור אפס אינו $00; זה 30 דולר. $00 פירושו Nul. בתוכנית, ייתכן שיש נקודה שבה התוכנית צריכה לחכות ללחיצת מקש. הקוד לכך הוא:

המתן JSR GETIN
CMP #$00
צפרדע חכה

בשורה הראשונה, 'WAIT' היא תווית המזהה את כתובת ה-RAM שבה מוכנסת (מוקלדת) הוראת JSR. GETIN היא גם כתובת. זוהי הכתובת של הראשון מבין שלושת הבתים המתאימים בטבלת הקפיצות. הערך GETIN, כמו גם כל הערכים בטבלת הקפיצות (פרט לשלושת האחרונים), מורכב משלושה בתים. הבית הראשון של הערך הוא הוראת JSR. שני הבתים הבאים הם הכתובת של הגוף של תת-השגרה הממשית של GETIN שעדיין נמצאת ב-ROM (OS) אך מתחת לטבלת הקפיצה. אז, הערך אומר לקפוץ לשגרת המשנה GETIN. אם תור המקלדת אינו ריק, GETIN מכניס את קוד מפתח ASCII של תור First-In-First-Out לתוך המצבר. אם התור ריק, Null ($00) מוכנס למצבר.

ההוראה השנייה משווה את ערך המצבר ל-$00. אם זה 00$, זה אומר שתור המקלדת ריק, והפקת ה-CMP שולחת 1 לדגל ה-Z של אוגר המצב של המעבד (נקרא בפשטות אוגר סטטוס). אם הערך ב-A אינו $00, הוראת ה-CMP שולחת 0 לדגל ה-Z של אוגר המצב.

ההוראה השלישית שהיא 'BEQ WAIT' שולחת את התוכנית חזרה להוראה הראשונה אם דגל ה-Z של אוגר המצב הוא 1. ההוראות הראשונה, השנייה והשלישית מבוצעות שוב ושוב לפי הסדר עד ללחיצה על מקש במקלדת . אם אף פעם לא נלחץ על מקש, המחזור חוזר על עצמו ללא הגבלת זמן. קטע קוד כזה נכתב בדרך כלל עם קטע קוד תזמון שיוצא מהלולאה לאחר זמן מה אם לא נלחץ על מקש (עיין בדיון הבא).

הערה : המקלדת היא התקן הקלט המוגדר כברירת מחדל והמסך הוא התקן הפלט המוגדר כברירת מחדל.

5.4 ערוץ, מספר מכשיר ומספר קובץ לוגי

הציוד ההיקפי שבו פרק זה משתמש כדי להסביר את מערכת ההפעלה Commodore-64 הם המקלדת, המסך (צג), כונן הדיסקים עם התקליטון, המדפסת והמודם שמתחבר דרך ממשק RS-232C. כדי שהתקשורת תתקיים בין התקנים אלה ליחידת המערכת (מיקרו-מעבד וזיכרון), יש ליצור ערוץ.

ערוץ מורכב ממאגר, מספר מכשיר, מספר קובץ לוגי, ובאופן אופציונלי כתובת משנית. ההסבר למונחים אלה הוא כדלקמן:

מאגר
שימו לב מהסעיף הקודם שכאשר מקש נלחץ, הקוד שלו חייב לעבור למיקום בתים ב-RAM של סדרה של עשרה מיקומים רצופים. סדרה זו של עשרה מיקומים היא מאגר המקלדת. לכל התקן קלט או פלט (היקפי) יש סדרה של מיקומים רצופים ב-RAM הנקראים מאגר.

מספר מכשיר
עם ה-Commodore-64, כל ציוד היקפי ניתן עם מספר מכשיר. הטבלה הבאה מציגה את המכשירים השונים ומספריהם:

טבלה 5.41
מספרי התקנים של קומודור 64 והמכשירים שלהם
מספר התקן
0 מקלדת
1 כונן קלטות
2 ממשק RS 232C לדוגמא. מודם
3 מָסָך
4 מדפסת מס' 1
5 מדפסת מס' 2
6 פלוטר מס' 1
7 פלוטר מס' 2
8 כונן דיסק
9
¦
¦
¦
30
מ-8 (כולל) עד ​​22 התקני אחסון נוספים

ישנם שני סוגים של יציאות למחשב. סוג אחד הוא חיצוני, על המשטח האנכי של יחידת המערכת. הסוג השני הוא פנימי. יציאה פנימית זו היא אוגר. ל-Commodore-64 יש ארבע יציאות פנימיות: יציאה A ויציאה B עבור CIA 1 ויציאה A ויציאה B עבור CIA 2. יש יציאה חיצונית אחת עבור ה-Commodore-64 אשר נקראת יציאה טורית. המכשירים עם המספר 3 כלפי מעלה מחוברים ליציאה הטורית. הם מחוברים בשרשרת דייזי (אחד שמחובר מאחורי השני), שכל אחד מהם ניתן לזיהוי לפי מספר המכשיר שלו. המכשירים עם המספר 8 כלפי מעלה הם בדרך כלל התקני האחסון.

הערה : התקן הקלט המוגדר כברירת מחדל הוא המקלדת עם מספר ההתקן 0. התקן הפלט המוגדר כברירת מחדל הוא המסך עם מספר ההתקן 3.

מספר קובץ לוגי
מספר קובץ לוגי הוא מספר שניתן עבור מכשיר (ציוד היקפי) לפי סדר פתיחתו לגישה אליו. הם נעים בין 010 ל-255 10 .

כתובת משנית
תארו לעצמכם ששני קבצים (או יותר מקובץ אחד) נפתחים בדיסק. כדי להבדיל בין שני קבצים אלה, נעשה שימוש בכתובות המשניות. כתובות משניות הן מספרים המשתנים ממכשיר למכשיר. המשמעות של 3 ככתובת משנית למדפסת שונה מהמשמעות של 3 ככתובת משנית לכונן דיסקים. המשמעות תלויה בתכונות כמו מתי קובץ נפתח לקריאה או מתי קובץ נפתח לכתיבה. המספרים המשניים האפשריים הם מ-0 10 עד 15 10 עבור כל מכשיר. עבור מכשירים רבים, המספר 15 משמש לשליחת פקודות.

הערה : מספר המכשיר ידוע גם ככתובת המכשיר והמספר המשני ידוע גם ככתובת משנית.

זיהוי יעד היקפי
עבור מפת הזיכרון של Commodore המוגדרת כברירת מחדל, כתובות הזיכרון מ-$0200 עד $02FF (עמוד 2) משמשות אך ורק את מערכת ההפעלה ב-ROM (Kernal) ולא את מערכת ההפעלה בתוספת שפת BASIC. אם כי BASIC עדיין יכול להשתמש במיקומים דרך מערכת ההפעלה ROM.

המודם והמדפסת הם שני מטרות היקפיות שונות. אם שני קבצים נפתחים מהדיסק, אלה שני יעדים שונים. עם מפת הזיכרון המוגדרת כברירת מחדל, ישנן שלוש טבלאות (רשימות) עוקבות שניתן לראות אותן כטבלה אחת גדולה. שלוש הטבלאות הללו מכילות את הקשר בין מספרי הקבצים הלוגיים, מספרי ההתקנים והכתובות המשניות. עם זה, ערוץ ספציפי או יעד קלט/פלט הופך לזיהוי. שלושת הטבלאות נקראות File Tables. כתובות ה-RAM ומה שיש להן הן:

$0259 - $0262: טבלה עם תווית, LAT, של עד עשרה מספרי קבצים לוגיים פעילים.
$0263 - $026C: טבלה עם תווית, FAT, של עד עשרה מספרי מכשירים תואמים.
$026D - $0276: טבלה עם תווית, SAT, של עשר כתובות משניות מתאימות.

כאן, '-' פירושו 'אל', ומספר לוקח בייט אחד.

הקורא עשוי לשאול, 'מדוע המאגר עבור כל מכשיר אינו כלול בזיהוי ערוץ?' ובכן, התשובה היא שעם הקומודור-64, לכל מכשיר חיצוני (היקפי) יש סדרה קבועה של בתים ב-RAM (מפת זיכרון). ללא שום ערוץ פתוח, עמדותיהם עדיין שם בתוך הזיכרון. המאגר עבור המקלדת, למשל, קבוע מ-$0277 ל-$0280 (כולל) עבור מפת הזיכרון המוגדרת כברירת מחדל.

תת שגרות SETLFS ו-SETNAM של Kernal
SETLFS ו-SETNAM הם שגרות Kernal. ניתן לראות ערוץ כקובץ לוגי. כדי שייפתח ערוץ, יש להפיק את מספר הקובץ הלוגי, מספר ההתקן וכתובת משנית אופציונלית. ייתכן שיהיה צורך גם בשם קובץ אופציונלי (טקסט). שגרת SETLFS מגדירה את מספר הקובץ הלוגי, מספר ההתקן וכתובת משנית אופציונלית. המספרים האלה מוכנסים בטבלאות שלהם. שגרת SETNAM מגדירה שם מחרוזת עבור הקובץ שעשוי להיות חובה עבור ערוץ אחד ואופציונלי עבור ערוץ אחר. זה מורכב מצביע (כתובת שני בתים) בזיכרון. המצביע מצביע על תחילת המחרוזת (שם) אשר עשויה להיות במקום אחר בזיכרון. שם המחרוזת מתחיל בבייט בעל אורך המחרוזת, ואחריו הטקסט (שם). השם הוא לכל היותר שישה עשר בתים (ארוך).

כדי לקרוא לשגרת SETLFS, תוכנית המשתמש צריכה לקפוץ (JSR) לכתובת $FFBA של טבלת הקפיצה של מערכת ההפעלה ב-ROM עבור מפת הזיכרון המוגדרת כברירת מחדל. זכור שלמעט ששת הבתים האחרונים של טבלת הקפיצות, כל ערך מורכב משלושה בתים. הבית הראשון הוא הוראת ה-JSR, שקופצת לאחר מכן אל תת-השגרה, מתחילה בכתובת בשני הבייטים הבאים. כדי לקרוא לשגרת SETNAM, תוכנית המשתמש צריכה לקפוץ (JSR) לכתובת $FFBD של טבלת הקפיצה של מערכת ההפעלה ב-ROM. השימוש בשתי השגרות הללו מוצג בדיון הבא.

5.5 פתיחת ערוץ, פתיחת קובץ לוגי, סגירת קובץ לוגי וסגירת כל ערוצי הקלט/פלט

ערוץ מורכב ממאגר זיכרון, מספר קובץ לוגי, מספר מכשיר (כתובת מכשיר) וכתובת משנית אופציונלית (מספר). קובץ לוגי (הפשטה) המזוהה על ידי מספר קובץ לוגי יכול להתייחס לציוד היקפי כגון מדפסת, מודם, כונן דיסקים וכו'. לכל אחד מההתקנים השונים הללו צריך להיות מספרי קבצים לוגיים שונים. יש הרבה קבצים בדיסק. קובץ לוגי יכול להתייחס גם לקובץ מסוים בדיסק. לקובץ הספציפי הזה יש גם מספר קובץ לוגי השונה מאלה של הציוד ההיקפי כגון המדפסת או המודם. מספר הקובץ הלוגי ניתן על ידי המתכנת. זה יכול להיות כל מספר מ-010 ($00) עד 25510 ($FF).

שגרת SETLFS של מערכת ההפעלה
שגרת OS SETLFS שאליו ניתן לגשת באמצעות קפיצה (JSR) לטבלת הקפיצות של OS ROM ב-$FFBA מגדירה את הערוץ. זה צריך לשים את מספר הקובץ הלוגי בטבלת הקבצים שהיא LAT ($0259 - $0262). זה צריך לשים את מספר ההתקן המתאים בטבלת הקבצים שהוא FAT ($0263 - $026C). אם הגישה לקובץ (המכשיר) זקוקה למספר משני, היא צריכה לשים את הכתובת המשנית (המספר) המקבילה בטבלת הקבצים שהיא SAT ($026D - $0276).

על מנת לפעול, תת-השגרה SETLFS צריכה להשיג את מספר הקובץ הלוגי ממצבר µP; הוא צריך להשיג את מספר ההתקן מהאוגר של µP X. במידת הצורך על ידי הערוץ, הוא צריך להשיג את הכתובת המשנית מהאוגר µP Y.

מספר הקובץ הלוגי נקבע על ידי המתכנת. מספרי הקבצים הלוגיים המתייחסים למכשירים שונים שונים. כעת, לפני התקשרות לשגרת SETLFS, המתכנת צריך להכניס את המספר של הקובץ הלוגי לתוך מצבר µP. מספר המכשיר נקרא מטבלה (מסמך) כמו בטבלה 5.41. המתכנת צריך גם להכניס את מספר ההתקן לרישום µP X. הספק למכשיר כגון מדפסת, כונן דיסקים וכדומה מספק את הכתובות המשניות האפשריות ומשמעויותיהן עבור המכשיר. אם הערוץ צריך כתובת משנית, המתכנת צריך להשיג אותה מהמסמך שסופק עם המכשיר (היקפי). אם הכתובת המשנית (המספר) נחוצה, המתכנת צריך להכניס אותה לרישום µP Y לפני שיקרא לתת-שגרת SETLFS. אם אין צורך בכתובת משנית, המתכנת צריך להכניס את המספר $FF לרישום µP Y לפני שהוא מתקשר לתת-שגרת SETLFS.

תת-השגרה SETLFS נקראת ללא שום ארגומנט. הטיעונים שלה כבר נמצאים בשלושת הרשמים של ה-6502 µP. לאחר הכנסת המספרים המתאימים לרשומות, השגרה נקראת בתוכנית פשוט עם הדברים הבאים בשורה נפרדת:

JSR SETLFS

השגרה מכניסה את המספרים השונים כראוי לטבלאות הקבצים שלהם.

שגרת מערכת ההפעלה SETNAM
ניתן לגשת לשגרת OS SETNAM על ידי קפיצה (JSR) לטבלת הקפיצות של OS ROM ב-$FFBD. לא לכל היעדים יש שמות קבצים. עבור אלה שיש להם יעדים (כמו הקבצים בדיסק), יש להגדיר את שם הקובץ. נניח ששם הקובץ הוא 'mydocum' המורכב מ-7 בתים ללא המירכאות. נניח שהשם הזה נמצא במיקומים של $C101 עד $C107 (כולל) והאורך של $07 הוא במיקום $C100. כתובת ההתחלה של תווי המחרוזת היא $C101. הבית התחתון של כתובת ההתחלה הוא $01 והבית הגבוה יותר הוא $C1.

לפני הקריאה לשגרת ה-SETNAM, המתכנת צריך להכניס את המספר של $07 (אורך המחרוזת) לתוך מצבר µP. הבת התחתון של כתובת ההתחלה של המחרוזת של $01 מוכנס לרשום µP X. הבת הגבוהה יותר של כתובת ההתחלה של המחרוזת של $C1 מוכנס לאגר µP Y. תת-השגרה נקראת בפשטות עם הדברים הבאים:

JSR SETNAM

שגרת SETNAM מקשרת את הערכים משלושת האוגרים עם הערוץ. הערכים לא צריכים להישאר ברשומות לאחר מכן. אם הערוץ לא צריך שם קובץ, המתכנת צריך לשים $00 בצובר µP. במקרה זה, מתעלמים מהערכים שנמצאים באוגרי X ו-Y.

שגרת OPEN של מערכת ההפעלה
ניתן לגשת לשגרת OS OPEN על ידי קפיצה (JSR) לטבלת הזינוק של OS ROM ב-$FFC0. שגרה זו משתמשת במספר הקובץ הלוגי, מספר ההתקן (והמאגר), כתובת משנית אפשרית ושם קובץ אפשרי, כדי לספק חיבור בין מחשב הקומודור לקובץ בהתקן החיצוני או ההתקן החיצוני עצמו.

שגרה זו, כמו כל שאר שגרות ה-ROM של Commodore OS, אינה יכולה להתווכח. למרות שהוא משתמש באוגרי µP, אף אחד מהאוגרים לא היה צריך להיטען מראש עם ארגומנטים (ערכים) עבורו. כדי לקודד אותו, פשוט הקלד את הדברים הבאים לאחר שנקראים SETLFS ו-SETNAM:

JSR פתוח

עלולות להתרחש שגיאות בשגרת OPEN. לדוגמה, ייתכן שהקובץ לא יימצא לקריאה. כאשר מתרחשת שגיאה, השגרה נכשלת ומכניסה את מספר השגיאה המתאים למצבר µP, ומגדירה את דגל ה-carrier (ל-1) של אוגר המצב µP. הטבלה הבאה מספקת את מספרי השגיאות ואת המשמעויות שלהם:

טבלה 5.51
מספרי שגיאה של Kernal והמשמעויות שלהם עבור OS ROM OPEN שגרה
מספר שגיאה תיאור דוגמא
1 יותר מדי קבצים פתח כאשר עשרה קבצים כבר נפתחים
2 קובץ פתוח פתוח 1,3: פתוח 1,4
3 הקובץ לא פתוח הדפס מס' 5 ללא OPEN
4 הקובץ לא נמצא טען 'NONEXISTENF',8
5 המכשיר אינו קיים פתוח 11,11: הדפס #11
6 לא להזין קובץ פתח את 'SEQ,S,W': GET#8,X$
7 לא קובץ פלט פתוח 1,0: הדפס מס' 1
8 FILENAME חסר טען '',8
9 מכשיר לא חוקי מס. טען 'תוכנית', 3

טבלה זו מוצגת באופן שסביר שהקורא יראה במקומות רבים אחרים.

שגרת CHKIN של מערכת ההפעלה
ניתן לגשת לשגרת OS CHKIN על ידי קפיצה (JSR) לטבלת הזינוק של OS ROM ב-$FFC6. לאחר פתיחת קובץ (קובץ לוגי), יש להחליט אם הפתיחה היא לקלט או פלט. שגרת CHKIN הופכת את הפתיחה לערוץ קלט. שגרה זו צריכה לקרוא את מספר הקובץ הלוגי מאוגר µP X. לכן, המתכנת צריך להכניס את מספר הקובץ הלוגי לרישום X לפני שיתקשר לשגרה הזו. זה נקרא פשוט כמו:

JSR CHKIN

שגרת CHKOUT של מערכת ההפעלה
ניתן לגשת לשגרת OS CHKOUT על ידי קפיצה (JSR) לטבלת הקפיצות של OS ROM ב-$FFC9. לאחר פתיחת קובץ (קובץ לוגי), יש להחליט אם הפתיחה היא לקלט או פלט. שגרת CHKOUT הופכת את הפתיחה לערוץ פלט. שגרה זו צריכה לקרוא את מספר הקובץ הלוגי מאוגר µP X. לכן, המתכנת צריך להכניס את מספר הקובץ הלוגי לרישום X לפני שיתקשר לשגרה הזו. זה נקרא פשוט כמו:

JSR CHKOUT

שגרת OS CLOSE
ניתן לגשת לשגרת OS CLOSE על ידי קפיצה (JSR) לטבלת הזינוק של OS ROM ב-$FFC3. לאחר פתיחת קובץ לוגי והעברת הבייטים, יש לסגור את הקובץ הלוגי. סגירת הקובץ הלוגי משחררת את המאגר ביחידת המערכת לשימוש בקובץ לוגי אחר שעדיין יש לפתוח. הפרמטרים המתאימים בשלושת טבלאות הקבצים נמחקים גם כן. מיקום ה-RAM עבור מספר הקבצים הפתוחים מופחת ב-1.

כאשר המחשב מופעל, יש איפוס חומרה עבור המיקרו-מעבד ושבבים ראשיים אחרים (מעגלים משולבים) בלוח האם. זה מלווה באתחול של כמה מיקומי זיכרון RAM וכמה רישומים בכמה שבבים בלוח האם. בתהליך האתחול, מיקום הזיכרון בתים של הכתובת $0098 בעמוד אפס ניתן עם התווית NFILES או LDTND, בהתאם לגרסת מערכת ההפעלה. בזמן שהמחשב פועל, מיקום זה של 8 סיביות בבתים אחד מכיל את מספר הקבצים הלוגיים שנפתחים, ואת אינדקס כתובות ההתחלה של שלושת טבלאות הקבצים העוקבות. במילים אחרות, לבייט הזה יש את מספר הקבצים הפתוחים אשר מופחת ב-1 כאשר הקובץ הלוגי נסגר. כאשר הקובץ הלוגי נסגר, הגישה להתקן הטרמינל (יעד) או לקובץ בפועל בדיסק אינה אפשרית יותר.

על מנת לסגור קובץ לוגי, המתכנת צריך להכניס את מספר הקובץ הלוגי לתוך מצבר µP. זהו אותו מספר קובץ לוגי המשמש בפתיחת הקובץ. שגרת CLOSE צריכה את זה כדי לסגור את הקובץ המסוים הזה. כמו שגרות אחרות של OS ROM, שגרת CLOSE לא לוקחת ארגומנט, אם כי הערך שבו נעשה שימוש מהמצבר הוא במידת מה ארגומנט. שורת ההוראות של שפת ההרכבה היא פשוט:

JSR סגור

תת-השגרות המותאמות אישית או המוגדרות מראש של 6502 שפת הרכבה (שגרות) אינן לוקחות ארגומנטים. עם זאת, הטיעונים מגיעים בצורה לא פורמלית על ידי הצבת הערכים שבהם תת-השגרה תשתמש באוגרי המיקרו-מעבד.

שגרת CLRCHN
גישה לשגרת OS CLRCHN היא על ידי קפיצה (JSR) לטבלת הקפיצות של OS ROM ב-$FFCC. CLRCHN קיצור של CLeaR CHanneL. כאשר קובץ לוגי נסגר, הפרמטרים שלו של מספר קובץ לוגי, מספר מכשיר וכתובת משנית אפשרית נמחקים. אז, הערוץ עבור הקובץ הלוגי נוקה.

המדריך אומר ששגרת OS CLRCHN מנקה את כל הערוצים שנפתחו ומשחזרת את מספרי ברירת המחדל של ההתקנים וברירות מחדל אחרות. האם זה אומר שניתן לשנות את מספר ההתקן של ציוד היקפי? ובכן, לא לגמרי. במהלך אתחול מערכת ההפעלה, מיקום הבתים של הכתובת $0099 מסופק עם התווית DFLTI כדי להחזיק את מספר התקן הקלט הנוכחי כאשר המחשב פועל. הקומודור-64 יכול לגשת רק לציוד היקפי אחד בכל פעם. במהלך אתחול מערכת ההפעלה, מיקום הבתים של הכתובת $009A מסופק עם תווית DFLTO כדי להחזיק את מספר התקן הפלט הנוכחי כאשר המחשב פועל.

כאשר תת-השגרה CLRCHN נקראת, היא מגדירה את משתנה DFLTI ל-0 ($00) שהוא מספר ברירת המחדל של התקן הקלט (מקלדת). הוא מגדיר את משתנה DFLTO ל-3 ($03) שהוא מספר ברירת המחדל של התקן הפלט (מסך). משתני מספר מכשיר אחרים מאופסים באופן דומה. זו המשמעות של איפוס (או שחזור) התקני הקלט/פלט למצב נורמלי (ערכי ברירת מחדל).

המדריך של Commodore-64 אומר שלאחר קריאת שגרת CLRCHN, הקבצים הלוגיים שנפתחו נשארים פתוחים ועדיין יכולים להעביר את הבייטים (הנתונים). המשמעות היא ששגרת CLRCHN אינה מוחקת את הערכים התואמים בטבלאות הקבצים. השם CLRCHN הוא די מעורפל במשמעותו.

5.6 שליחת הדמות למסך

המעגל המשולב הראשי (IC) לטיפול בהצגת התווים והגרפיקה למסך נקרא Video Interface Controller (שבב) אשר מקוצר בשם VIC ב-Commodore-64 (למעשה VIC II עבור VIC גרסה 2). כדי שמידע (ערכים) יעבור למסך, עליו לעבור דרך VIC II לפני שהוא מגיע למסך.

המסך מורכב מ-25 שורות ו-40 עמודות של תאי אופי. זה עושה 40 x 25 = 1000 תווים שניתן להציג על המסך. ה-VIC II קורא את מיקומי הבתים הרצופים של 1000 זיכרון RAM בהתאמה עבור תווים. 1000 המיקומים האלה ביחד ידועים כזיכרון מסך. מה שנכנס ל-1000 המיקומים האלה הם קודי התווים. עבור Commodore-64, קודי התווים שונים מקודי ASCII.

קוד תו אינו דפוס תו. יש גם מה שמכונה תווים ROM. ROM התווים מורכב מכל מיני תבניות, שחלקן תואמות לתבניות התווים במקלדת. ROM התווים שונה מזיכרון המסך. כאשר יש להציג תו על המסך, קוד התו נשלח למיקום בין 1000 המיקומים של זיכרון המסך. משם, התבנית המתאימה נבחרת מתוך ROM התווים שאמור להיות מוצג על המסך. בחירת התבנית הנכונה ב-ROM התווים מקוד תו נעשית על ידי VIC II (חומרה).

למיקומי זיכרון רבים בין $D000 ל-$DFFF יש שתי מטרות: הם משמשים לטיפול בפעולות הקלט/פלט מלבד המסך או משמשים כ-ROM של תווים למסך. מדובר בשני גושי זיכרון. האחד הוא RAM והשני הוא ROM ל-ROM של תו. ההחלפה של הבנקים לטיפול בקלט/פלט או בדפוסי התווים (ROM של תווים) נעשית על ידי תוכנה (שגרה של מערכת ההפעלה ב-ROM מ-$F000 ל-$FFFF).

הערה : ל-VIC יש אוגרים שממוענים עם כתובות של מרחב הזיכרון בטווח של $D000 ו-$DFFF.

שגרת CHROUT
ניתן לגשת לשגרת OS CHROUT על ידי קפיצה (JSR) לטבלת הקפיצות של OS ROM ב-$FFD2. שגרה זו, כאשר היא נקראת, לוקחת את הבתים שהמתכנת הכניס לצובר µP ומדפיסה במסך שבו נמצא הסמן. קטע הקוד להדפסת התו 'E', למשל, הוא:

LDA #$05
CHROUT

ה-0516 אינו קוד ASCII עבור 'E'. ל-Commodore-64 יש קודי תווים משלו למסך שבו 05$ פירושו 'E'. המספר #$05 מונח בזיכרון המסך לפני ש-VIC שולח אותו למסך. שתי שורות קידוד אלו אמורות להגיע לאחר הגדרת הערוץ, פתיחת הקובץ הלוגי ושגרת CHKOUT נקראת עבור הפלט. הקוד המלא הוא:

; הגדרת ערוץ
LDA #$40 ; מספר קובץ לוגי
LDX #$03 ; מספר המכשיר למסך הוא $03
LDY #$FF ; אין כתובת משנית
JSR SETLFS ; הגדרת ערוץ תקין
; אין SETNAM מכיוון שהמסך לא צריך שם
;
; פתח קובץ לוגי
JSR פתוח
; הגדר ערוץ לפלט
LDX #$40 ; מספר קובץ לוגי
JSR CHKOUT
;
; פלט char למסך
LDA #$05
JSR CHROUT
; סגור קובץ לוגי
LDA #40$
JSR סגור

יש לסגור את הפתיחה לפני הפעלת תוכנית אחרת. נניח שמשתמש המחשב מקליד תו למקלדת כאשר צפוי. התוכנית הבאה מדפיסה תו מהמקלדת למסך:

; הגדרת ערוץ
LDA #$40 ; מספר קובץ לוגי
LDX #$03 ; מספר המכשיר למסך הוא $03
LDY #$FF ; אין כתובת משנית
JSR SETLFS ; הגדרת ערוץ תקין
; אין SETNAM מכיוון שהמסך לא צריך שם
;
; פתח קובץ לוגי
JSR פתוח
; הגדר ערוץ לפלט
LDX #$40 ; מספר קובץ לוגי
JSR CHKOUT
;
; הזנת תווים מהמקלדת
המתן JSR GETIN ; מכניס $00 ל-A אם תור המקלדת ריק
CMP #$00 ; אם 00$ הלך ל-A, אז Z הוא 1 עם ההשוואה
BEQ WAIT ; קבל שוב מהתור אם 0 הלך לצובר
BNE PRNSCRN ; עבור אל PRNSCRN אם Z הוא 0, כי ל-A אין יותר $00
; פלט char למסך
PRNSCRN JSR CHROUT ; שלח את ה-char ב-A למסך
; סגור קובץ לוגי
LDA #40$
JSR סגור

הערה : WAIT ו-PRNSCRN הן התוויות המזהות את הכתובות. הבת מהמקלדת שמגיעה לצבר µP הוא קוד ASCII. הקוד המתאים שיישלח למסך על ידי Commodore-64 חייב להיות שונה. זה לא נלקח בחשבון בתוכנית הקודמת למען הפשטות.

5.7 שליחה וקבלה של בתים עבור כונן דיסק

ישנם שני מתאמי ממשק מורכבים ביחידת המערכת (לוח האם) של Commodore-64 הנקראים VIA #1 ו-CIA #2. לכל CIA יש שתי יציאות מקבילות שנקראות פורט A ופורט B. יש יציאה חיצונית במשטח האנכי בחלק האחורי של יחידת מערכת Commodre-64 שנקראת יציאה טורית. ליציאה הזו יש 6 פינים, אחד מהם מיועד לנתונים. הנתונים נכנסים או יוצאים מיחידת המערכת בסדרה, ביט אחד בכל פעם.

שמונה ביטים מקבילים מהיציאה הפנימית A של CIA #2, למשל, יכולים לצאת מיחידת המערכת דרך היציאה הטורית החיצונית לאחר שהומרו לנתונים הטוריים על ידי אוגר משמרת ב-CIA. נתונים טוריים של שמונה סיביות מהיציאה הטורית החיצונית יכולים להיכנס ליציאה הפנימית A של CIA #2 לאחר שהומרו לנתונים המקבילים על ידי אוגר משמרות ב-CIA.

יחידת המערכת Commodore-64 (יחידת בסיס) משתמשת בכונן דיסקים חיצוני עם דיסקט. ניתן לחבר מדפסת לכונן דיסקים זה בצורת שרשרת דייזי (חיבור התקנים בסדרה כמחרוזת). כבל הנתונים של כונן הדיסקים מחובר ליציאה הטורית החיצונית של יחידת המערכת Commodore-64. המשמעות היא שגם מדפסת עם שרשרת דייזי מחוברת לאותה יציאה טורית. שני מכשירים אלו מזוהים על ידי שני מספרי מכשירים שונים (בדרך כלל 8 ו-4, בהתאמה).

שליחה או קבלה של הנתונים עבור כונן הדיסקים מתבצעת באותו הליך כפי שתואר קודם לכן. זה:

  • הגדרת שם הקובץ הלוגי (מספר) זהה לזה של קובץ הדיסק בפועל באמצעות שגרת SETNAM.
  • פתיחת הקובץ הלוגי באמצעות שגרת OPEN.
  • החלטה אם זה קלט או פלט באמצעות שגרת CHKOUT או CHKIN.
  • שליחה או קבלה של הנתונים באמצעות הוראת STA ו/או LDA.
  • סגירת הקובץ הלוגי באמצעות שגרת CLOSE.

יש לסגור את הקובץ הלוגי. סגירת הקובץ הלוגי סוגרת למעשה את הערוץ המסוים הזה. בעת הגדרת הערוץ עבור כונן הדיסקים, מספר הקובץ הלוגי נקבע על ידי המתכנת. זהו מספר בין $00 ל-$FF (כולל). זה לא צריך להיות מספר שכבר נבחר עבור כל מכשיר אחר (או קובץ בפועל). מספר ההתקן הוא 8 אם יש רק כונן דיסק אחד. הכתובת המשנית (מספר) מתקבלת מהמדריך של כונן הדיסקים. התוכנית הבאה משתמשת ב-2. התוכנה כותבת את האות 'E' (ASCII) לקובץ בדיסק בשם 'mydoc.doc'. מניחים ששם זה מתחיל בכתובת הזיכרון של $C101. אז, הבית התחתון של $01 חייב להיות ב-X אוגר והבית הגבוה יותר של $C1 צריך להיות באוגר Y לפני קריאת השגרה SETNAM. לפנקס A צריך להיות גם המספר $09 לפני הקריאה לשגרת SETNAM.

; הגדרת ערוץ
LDA #$40 ; מספר קובץ לוגי
LDX #$08 ; מספר התקן עבור כונן הדיסק הראשון
LDY #$02 ; כתובת משנית
JSR SETLFS ; הגדרת ערוץ תקין
;
; לקובץ בכונן הדיסק צריך שם (כבר בזיכרון)
LDA #$09
LDX #$01
LDY#$C1
JSR SETNAM
; פתח קובץ לוגי
JSR פתוח
; הגדר ערוץ לפלט
LDX #$40 ; מספר קובץ לוגי
JSR CHKOUT ;לכתיבה
;
; פלט char לדיסק
LDA #45$
JSR CHROUT
; סגור קובץ לוגי
LDA #40$
JSR סגור

על מנת לקרוא בייט מהדיסק לתוך האוגר µP Y, חזור על התוכנית הקודמת עם השינויים הבאים: במקום 'JSR CHKOUT ; לכתיבה', השתמש ב-'JSR CHKIN ; לקריאה'. החלף את קטע הקוד עבור '; פלט char לדיסק' עם הדברים הבאים:

; קלט char מהדיסק
JSR CHRIS

אל שגרת OS CHRIN ניתן לגשת על ידי קפיצה (JSR) לטבלת הקפיצות של OS ROM ב-$FFCF. השגרה הזו, כאשר היא נקראת, מקבלת בייט מערוץ שכבר מוגדר כערוץ קלט ומכניסה אותו לאגר µP A. ניתן להשתמש בשגרת GETIN ROM OS גם במקום CHRIN.

שליחת בייט למדפסת
שליחת בייט למדפסת מתבצעת באופן דומה לשליחת בייט לקובץ בדיסק.

5.8 שגרת ה-SAVE של מערכת ההפעלה

ניתן לגשת לשגרת ה-SAVE של מערכת ההפעלה על ידי קפיצה (JSR) לטבלת הזינוק של מערכת ההפעלה ROM ב-$FFD8. שגרת OS SAVE ב-ROM שומרת (שולפת) קטע מהזיכרון לדיסק כקובץ (עם שם). יש לדעת את כתובת ההתחלה של הקטע בזיכרון. גם כתובת הסיום של המדור צריכה להיות ידועה. הבית התחתון של כתובת ההתחלה ממוקם בעמוד אפס ב-RAM בכתובת $002B. הבית הגבוה יותר של כתובת ההתחלה ממוקם במיקום הזיכרון הבא של הבתים בכתובת $002C. בעמוד אפס, התווית TXTTAB מתייחסת לשתי הכתובות הללו, אם כי TXTTAB מתכוונת למעשה לכתובת $002B. הבית התחתון של כתובת הקצה ממוקם באוגר µP X. הבת הגבוהה יותר של כתובת הקצה פלוס 1 ממוקמת באוגר µP Y. האוגר µP A לוקח את הערך של $2B עבור TXTTAB ($002B). עם זה, ניתן לקרוא לשגרת SAVE עם הדברים הבאים:

JSR SAVE

החלק של הזיכרון שיש לשמור יכול להיות תוכנית שפת assembly או מסמך. דוגמה למסמך יכולה להיות מכתב או חיבור. כדי להשתמש בשגרת השמירה, יש לבצע את ההליך הבא:

  • הגדר את הערוץ באמצעות שגרת SETLFS.
  • הגדר את שם הקובץ הלוגי (מספר) זהה לזה של קובץ הדיסק בפועל באמצעות שגרת SETNAM.
  • פתח את הקובץ הלוגי באמצעות שגרת OPEN.
  • הפוך אותו לקובץ עבור הפלט באמצעות CHKOUT.
  • הקוד לשמירת הקובץ מגיע לכאן שמסתיים ב- 'JSR SAVE'.
  • סגור את הקובץ הלוגי באמצעות שגרת CLOSE.

התוכנית הבאה שומרת קובץ שמתחיל ממיקומי הזיכרון של $C101 עד $C200:

; הגדרת ערוץ
LDA #$40 ; מספר קובץ לוגי
LDX #$08 ; מספר התקן עבור כונן הדיסק הראשון
LDY #$02 ; כתובת משנית
JSR SETLFS ; הגדרת ערוץ תקין
;
; שם לקובץ בכונן דיסקים (כבר בזיכרון ב-$C301)
LDA #$09 ; אורך שם הקובץ
LDX #$01
LDY #$C3
JSR SETNAM
; פתח קובץ לוגי
JSR פתוח
; הגדר ערוץ לפלט
LDX #$40 ; מספר קובץ לוגי
JSR CHKOUT ; לכתיבה
;
; פלט קובץ לדיסק
LDA #$01
STA $2B ; TXTTAB
LDA #$C1
STA $2C
LDX #$00
LDY #$C2
LDA #$2B
JSR SAVE
; סגור קובץ לוגי
LDA #40$
JSR סגור

שימו לב שזו תוכנה ששומרת קטע נוסף של הזיכרון (לא קטע התכנית) בדיסק (דיסקט עבור Commodore-64).

5.9 שגרת הטעינה של מערכת ההפעלה

ניתן לגשת לשגרת ה-OS LOAD על ידי קפיצה (JSR) לטבלת הקפיצות של OS ROM ב-$FFD5. כאשר קטע (שטח גדול) מהזיכרון נשמר בדיסק, הוא נשמר עם כותרת בעלת כתובת ההתחלה של הקטע בזיכרון. תת שגרת OS LOAD טוענת את הבתים של קובץ לזיכרון. עם פעולת LOAD זו, הערך של המצבר צריך להיות 010 ($00). כדי שפעולת ה-LOAD תקרא את הכתובת ההתחלתית בכותרת הקובץ בדיסק ותכניס את הקבצים ל-RAM החל מכתובת זו, הכתובת המשנית לערוץ צריכה להיות 1 או 2 (התוכנית הבאה משתמשת ב-2). שגרה זו מחזירה את הכתובת פלוס 1 של מיקום ה-RAM הגבוה ביותר שנטען. משמעות הדבר היא שהבייט הנמוך של הכתובת האחרונה של הקובץ ב-RAM פלוס 1 מוכנס באוגר µP X, והבייט הגבוה של הכתובת האחרונה של הקובץ ב-RAM פלוס 1 מוכנס באוגר µP Y.

אם הטעינה לא מצליחה, האוגר µP A מכיל את מספר השגיאה (אולי 4, 5, 8 או 9). דגל ה-C של אוגר המצב של המיקרו-מעבד מוגדר גם הוא (עשה 1). אם הטעינה הצליחה, הערך האחרון של פנקס A אינו חשוב.

כעת, בפרק הקודם של קורס קריירה מקוון זה, ההוראה הראשונה של תוכנית שפת ההרכבה נמצאת בכתובת ב-RAM שבה התוכנית התחילה. זה לא חייב להיות ככה. זה אומר שההוראה הראשונה של תוכנית לא חייבת להיות בתחילת התוכנית ב-RAM. הוראת ההתחלה של תוכנית יכולה להיות בכל מקום בתוך הקובץ ב-RAM. למתכנת מומלץ לתייג את זה להתחיל הוראת שפת assembly עם START. עם זה, לאחר טעינת התוכנית, היא פועלת מחדש (מופעלת) עם הוראת שפת ההרכבה הבאה:

JSR START

'JSR START' נמצא בתוכנית שפת ההרכבה שטוענת את התוכנית להפעלה. לשפת assembly שטוענת קובץ שפת assembly אחר ומריצה את הקובץ הנטען יש את הליך הקוד הבא:

  • הגדר את הערוץ באמצעות שגרת SETLFS.
  • הגדר את שם הקובץ הלוגי (מספר) זהה לזה של קובץ הדיסק בפועל באמצעות שגרת SETNAM.
  • פתח את הקובץ הלוגי באמצעות שגרת OPEN.
  • הפוך אותו לקובץ לקלט באמצעות CHKIN.
  • הקוד לטעינת הקובץ נכנס לכאן ומסתיים ב-'JSR LOAD'.
  • סגור את הקובץ הלוגי באמצעות שגרת CLOSE.

התוכנה הבאה טוענת קובץ מהדיסק ומפעילה אותו:

; הגדרת ערוץ
LDA #$40 ; מספר קובץ לוגי
LDX #$08 ; מספר התקן עבור כונן הדיסק הראשון
LDY #$02 ; כתובת משנית
JSR SETLFS ; הגדרת ערוץ תקין
;
; שם לקובץ בכונן דיסקים (כבר בזיכרון ב-$C301)
LDA #$09 ; אורך שם הקובץ
LDX #$01
LDY #$C3
JSR SETNAM
; פתח קובץ לוגי
JSR פתוח
; הגדר ערוץ לקלט
LDX #$40 ; מספר קובץ לוגי
JSR CHKIN ; לקריאה
;
; קובץ קלט מהדיסק
LDA #$00
JSR LOAD
; סגור קובץ לוגי
LDA #40$
JSR סגור
; התחל את התוכנית הטעונה
JSR START

5.10 המודם והתקן RS-232

המודם הוא מכשיר (ציוד היקפי) הממיר את הביטים מהמחשב לאותות האודיו החשמליים המתאימים שישודרו על גבי קו הטלפון. בקצה המקבל, יש מודם לפני מחשב קולט. מודם שני זה ממיר את אותות האודיו החשמליים לביטים עבור המחשב המקבל.

מודם צריך להיות מחובר למחשב ביציאה חיצונית (במשטח האנכי של המחשב). תקן RS-232 מתייחס לסוג מסוים של מחברים אשר מחברים מודם למחשב (בעבר). במילים אחרות, למחשבים רבים בעבר הייתה יציאה חיצונית שהייתה מחבר RS-232 או מחבר תואם RS-232.

ליחידת המערכת Commodore-64 (מחשב) יש יציאה חיצונית במשטח האנכי האחורי שלה, הנקראת יציאת המשתמש. יציאת משתמש זו תואמת RS-232. ניתן לחבר שם מכשיר מודם. ה-Commodore-64 מתקשר עם מודם דרך יציאת משתמש זו. למערכת ההפעלה ROM של ה-Commodore-64 יש תתי שגרות לתקשורת עם מודם הנקרא RS-232 routines. לשגרות האלה יש ערכים בטבלת הקפיצות.

קצב שידור
הבת שמונה סיביות מהמחשב מומרת לסדרה של שמונה סיביות לפני שנשלח למודם. ההיפך נעשה מהמודם למחשב. קצב ה-baud הוא מספר הביטים המועברים בשנייה, בסדרה.

תחתית הזיכרון
המונח 'תחתית הזיכרון' אינו מתייחס למיקום בייט הזיכרון של הכתובת $0000. זה מתייחס למיקום ה-RAM הנמוך ביותר שבו המשתמש יכול להתחיל לשים את הנתונים והתוכניות שלו. כברירת מחדל, זה הוא $0800. נזכיר מהדיון הקודם שהרבה מהמיקומים בין $0800 ל-$BFFF משמשים את שפת המחשב BASIC ואת המתכנתים (המשתמשים) שלה. נותרו רק מיקומי הכתובות של $C000 עד $CFFF לשימוש עבור התוכניות והנתונים של שפת ה-Assembly; זה 4Kbytes מתוך 64Kbytes של הזיכרון.

ראש הזיכרון
באותם ימים, כשהלקוחות קנו את מחשבי Commodore-64, חלקם לא הגיעו עם כל מיקומי הזיכרון. למחשבים כאלה היה ROM עם מערכת ההפעלה שלו מ-$E000 ל-$FFFF. היה להם זיכרון RAM מ-$0000 ועד לגבול, שאינו $DFFF, ליד $E000. המגבלה הייתה מתחת ל-$DFFF והמגבלה הזו נקראת 'Top of Memory'. לכן, הזיכרון העליון אינו מתייחס למיקום $FFFF.

Commodore-64 Buffers לתקשורת RS-232
מאגר שידור
המאגר עבור שידור (פלט) RS-232 לוקח 256 בתים מהחלק העליון של הזיכרון כלפי מטה. המצביע עבור מאגר שידור זה מסומן כ-ROBUF. מצביע זה נמצא בעמוד אפס עם הכתובות של $00F9 ואחריהם $00FA. ROBUF למעשה מזהה $00F9. לכן, אם הכתובת לתחילת המאגר היא $BE00, הבית התחתון של $BE00, שהוא $00, נמצא במיקום $00F9 והבית הגבוה יותר של $BE00, שהוא $BE, נמצא ב-$00FA מקום.

מקבל מאגר
המאגר לקליטת ה-RS-232 בתים (קלט) לוקח 256 בתים מהחלק התחתון של המאגר המשדר. המצביע עבור מאגר קליטה זה מסומן כ-RIBUF. מצביע זה נמצא בעמוד אפס עם הכתובות $00F7 ואחריהם $00F8. RIBUF למעשה מזהה $00F7. לכן, אם הכתובת לתחילת המאגר היא $BF00, הביט התחתון של $BF00, שהוא $00, נמצא במיקום $00F7 והבייט הגבוה יותר של $BF00, שהוא $BF, נמצא ב-$00F8 מקום. אז, 512 בתים מחלק העליון של הזיכרון משמשים כמאגר ה-RAM הכולל של RS-232.

ערוץ RS-232
כאשר מודם מחובר ליציאת המשתמש (החיצונית), התקשורת למודם היא רק תקשורת RS-232. ההליך לקיום ערוץ RS-232 שלם הוא כמעט זהה לדיון הקודם, אבל עם הבדל אחד חשוב: שם הקובץ הוא קוד ולא מחרוזת בזיכרון. הקוד $0610 הוא בחירה טובה. זה אומר קצב העברת העברת נתונים של 300 סיביות לשנייה ועוד כמה פרמטרים טכניים. כמו כן, אין כתובת משנית. שים לב שמספר ההתקן הוא 2. ההליך להגדרת ערוץ RS-232 שלם הוא:

  • הגדרת הערוץ באמצעות שגרת SETLFS.
  • הגדרת שם הקובץ הלוגי, $0610.
  • פתיחת הקובץ הלוגי באמצעות שגרת OPEN.
  • הפיכתו לקובץ לפלט באמצעות CHKOUT או לקובץ לקלט באמצעות CHKIN.
  • שליחת הבתים הבודדים עם CHROUT או קבלת הבתים הבודדים עם GETIN.
  • סגירת הקובץ הלוגי באמצעות שגרת CLOSE.

ניתן לגשת לשגרת GETIN של מערכת ההפעלה על ידי קפיצה (JSR) לטבלת הקפיצות של מערכת ההפעלה ROM ב-$FFE4. שגרה זו, כאשר היא נקראת, לוקחת את הבתים הנשלחים למאגר המקלט ומכניסה (מחזירה) אותו לתוך מצבר µP.

התוכנית הבאה שולחת את הבית 'E' (ASCII) למודם המחובר ליציאת המשתמש תואמת RS-232:

; הגדרת ערוץ
LDA #$40 ; מספר קובץ לוגי
LDX #$02 ; מספר מכשיר עבור RS-232
LDY #$FF ; אין כתובת משנית
JSR SETLFS ; הגדרת ערוץ תקין
;
; השם של RS-232 הוא קוד, למשל. $0610
LDA #$02 ; אורך הקוד הוא 2 בתים
LDX #$10
LDY#$06
JSR SETNAM
;
; פתח קובץ לוגי
JSR פתוח
; הגדר ערוץ לפלט
LDX #$40 ; מספר קובץ לוגי
JSR CHKOUT
;
; פלט char ל-RS-232 למשל. מוֹדֶם
LDA #45$
JSR CHROUT
; סגור קובץ לוגי
LDA #40$
JSR סגור

כדי לקבל בייט, הקוד דומה מאוד, אלא ש-'JSR CHKOUT' מוחלף ב-'JSR CHKIN' ו:

LDA #45$
JSR CHROUT

מוחלף ב-'JSR GETIN' כשהתוצאה מועברת ל-A register.

שליחה או קבלה מתמשכת של בתים נעשית על ידי לולאה לשליחה או קבלה של קטע קוד, בהתאמה.

שימו לב שהקלט והפלט עם הקומודור דומים ברוב המקרים שלו מלבד המקלדת שבה חלק מהרוטינות לא נקראות על ידי המתכנת, אלא הן נקראות על ידי מערכת ההפעלה.

5.11 ספירה ותזמון

שקול את רצף הספירה לאחור שהוא:

2, 1, 0

זוהי ספירה לאחור מ-2 ל-0. כעת, שקול את רצף הספירה לאחור החוזרת על עצמה:

2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0

זוהי הספירה החוזרת לאחור של אותו רצף. הרצף חוזר על עצמו ארבע פעמים. ארבע פעמים אומר שהתזמון הוא 4. בתוך רצף אחד הוא סופר. חזרה על אותו רצף היא תזמון.

ישנם שני מתאמי ממשק מורכבים ביחידת המערכת של ה-Commodore-64. לכל CIA יש שני מעגלי מונה/טיימר בשם טיימר A (TA) וטיימר B (TB). מעגל הספירה אינו שונה ממעגל התזמון. המונה או הטיימר ב-Commodore-64 מתייחסים לאותו דבר. למעשה, כל אחד מהם מתייחס בעצם לאגרסטר אחד של 16 סיביות שסופר תמיד לאחור עד 0 בפולסי השעון של המערכת. ניתן להגדיר ערכים שונים לתוך האוגר של 16 סיביות. ככל שהערך גדול יותר, כך לוקח יותר זמן לספור לאפס. בכל פעם שאחד מהטיימרים עובר את האפס, ה IRQ אות פסיקה נשלח למיקרו-מעבד. כאשר הספירה יורדת מעבר לאפס, זה נקרא תת-זרימה.

בהתאם לאופן שבו מתוכנת מעגל הטיימר, טיימר יכול לפעול במצב חד פעמי או במצב רציף. עם האיור הקודם, מצב חד פעמי פירושו 'עשה 2, 1, 0' ועצור בזמן שפולסי השעון נמשכים. מצב רציף הוא כמו '2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0 וכו'.' שממשיך עם פעימות השעון. זה אומר שכאשר הוא עובר את האפס, אם לא ניתנת הוראה, רצף הספירה לאחור חוזר על עצמו. המספר הגדול ביותר הוא בדרך כלל הרבה יותר מ-2.

טיימר A (TA) של CIA #1 יוצר IRQ במרווחים קבועים (משכי זמן) כדי לטפל במקלדת. למעשה, זה למעשה כל 1/60 שנייה כברירת מחדל. IRQ נשלח למיקרו-מעבד כל 1/60 שניה. זה רק מתי IRQ נשלח שתוכנית יכולה לקרוא ערך מפתח מהתור של המקלדת (מאגר). זכור שלמיקרו-מעבד יש רק פין אחד עבור IRQ אוֹת. למיקרו-מעבד יש רק פין אחד עבור NMI אוֹת. האות ¯NMI למיקרו-מעבד מגיע תמיד מ-CIA #2.

לרגיסטר טיימר 16 סיביות יש שתי כתובות זיכרון: אחת לבייט נמוך ואחת לבייט גבוה יותר. לכל CIA יש שני מעגלי טיימר. שני ה-CIA זהים. עבור CIA #1, הכתובות של שני הטיימרים הן: DC04 ו-DC05 עבור TA ו-DC06 ו-DC07 עבור TB. עבור CIA #2, הכתובות של שני הטיימרים הן: DD04 ו-DD05 עבור TA ו-DD06 ו-DD07 עבור TB.

נניח שהמספר 25510 יישלח לטיימר TA של CIA #2 לספירה לאחור. 25510 = 00000000111111112 הוא בשש עשרה סיביות. 00000000111111112 = $000FFF הוא בהקסדצימלי. במקרה זה, $FF נשלח למרשם בכתובת $DD04, ו-$00 נשלח למרשם בכתובת $DD05 - little endianness. קטע הקוד הבא שולח את המספר לפנקס:

LDA #$FF
ציין $DD04
LDA #$00
ציין $DD05

למרות שלרגיסטרים ב-CIA יש כתובות RAM, הם נמצאים פיזית ב-CIA וה-CIA הוא IC נפרד מ-RAM או ROM.

זה לא הכל! כאשר הטיימר קיבל מספר לספירה לאחור, כמו בקוד הקודם, הספירה לאחור לא מתחילה. הספירה לאחור מתחילה כאשר בתים של שמונה סיביות נשלחו לאוגר הבקרה המתאים עבור הטיימר. הסיביות הראשונה של בית זה עבור אוגר הבקרה מציינת אם הספירה לאחור צריכה להתחיל או לא. ערך של 0 עבור סיביות ראשונה זו פירושו להפסיק את הספירה לאחור, בעוד שערך של 1 פירושו להתחיל בספירה לאחור. כמו כן, ה-byte צריך לציין אם הספירה לאחור היא במצב של ירייה אחת (חד פעמית) או במצב ריצה חופשית (מצב רציף). מצב צילום אחד סופר לאחור ומפסיק כאשר הערך של אוגר הטיימר הופך לאפס. במצב ריצה חופשית, הספירה לאחור חוזרת לאחר שמגיעה ל-0. הסיביות הרביעית (אינדקס 3) של הביט שנשלחת לאוגר הבקרה מציינת את המצב: 0 פירושו מצב ריצה חופשית ו-1 פירושו מצב חד-פעמי.

מספר מתאים להתחיל לספור במצב צילום אחד הוא 000010012 = $09 בהקסדצימלי. מספר מתאים להתחיל לספור במצב ריצה חופשית הוא 000000012 = $01 בהקסדצימלי. לכל אוגר טיימר יש אוגר בקרה משלו. ב-CIA #1, לאוגר הבקרה של טיימר A יש את כתובת ה-RAM של DC0E16 ולאוגר הבקרה של טיימר B יש את כתובת ה-RAM של DC0F16. ב-CIA #2, לאוגר הבקרה של טיימר A יש את כתובת ה-RAM של DD0E16 ולאוגר הבקרה של טיימר B יש את כתובת ה-RAM של DD0F16. כדי להתחיל לספור לאחור את המספר של שש עשרה סיביות ב-TA של CIA #2, במצב צילום אחד, השתמש בקוד הבא:

LDA #$09
STA $DD0E

כדי להתחיל לספור לאחור את מספר שש עשרה הסיביות ב-TA של CIA #2, במצב ריצה חופשית, השתמש בקוד הבא:

LDA #$01
STA $DD0E

5.12 ה IRQ ו NMI בקשות

למיקרו-מעבד 6502 יש את IRQ ו NMI קווים (סיכות). גם ל-CIA #1 וגם ל-CIA #2 יש את IRQ סיכה עבור המיקרו-מעבד. ה IRQ פין של CIA #2 מחובר ל- NMI סיכה של µP. ה IRQ פין של CIA #1 מחובר ל- IRQ סיכה של µP. אלה שני קווי הפסיקה היחידים שמחברים את המיקרו-מעבד. אז ה IRQ הסיכה של CIA #2 היא NMI מקור וניתן לראות אותו גם כקו ¯NMI.

ל-CIA #1 יש חמישה מקורות מיידיים אפשריים ליצירת IRQ אות עבור µP. CIA #2 זהה במבנה ל-CIA #1. אז, ל-CIA #2 יש את אותם חמשת מקורות מיידיים אפשריים להפקת אות ההפרעה הפעם, שהוא NMI אוֹת. זכור שכאשר µP מקבל את NMI אות, אם הוא מטפל ב IRQ בקשה, היא משעה זאת ומטפלת ב NMI בַּקָשָׁה. כאשר הוא מסיים לטפל ב NMI בקשה, לאחר מכן היא חוזרת לטיפול ב- IRQ בַּקָשָׁה.

CIA #1 מחובר בדרך כלל חיצונית למקלדת ולהתקן משחק כגון ג'ויסטיק. המקלדת משתמשת יותר ביציאה A של CIA #1 מאשר ביציאה B. התקן המשחק משתמש יותר ביציאת CIA #1 B מאשר ביציאה A שלו. CIA #2 בדרך כלל מחוברת חיצונית לכונן הדיסקים (משורשר בשרשרת למדפסת) והמודם. כונן הדיסקים משתמש יותר ביציאה A של CIA #2 (אם כי דרך היציאה הטורית החיצונית) מאשר ביציאה B שלו. המודם (RS-232) משתמש יותר ביציאת CIA #2 B מאשר ביציאה A שלו.

עם כל זה, איך יחידת המערכת יודעת מה גורם ל IRQ אוֹ NMI פסיקת? ל-CIA #1 ול-CIA #2 יש חמישה מקורות הפרעה מיידיים. אם אות ההפסקה ל-µP הוא NMI , המקור הוא אחד מחמשת המקורות המיידיים מ-CIA #2. אם אות ההפסקה ל-µP הוא IRQ , המקור הוא אחד מחמשת המקורות המיידיים מ-CIA #1.

השאלה הבאה היא, 'כיצד יחידת המערכת מבדילה בין חמשת המקורות המיידיים של כל CIA?' לכל CIA יש אוגר של שמונה סיביות הנקרא כ-Interrupt Control Register (ICR). ה-ICR משרת את שני הנמלים של ה-CIA. הטבלה הבאה מציגה את המשמעויות של שמונת הסיביות של אוגר בקרת הפסיקה, החל מסיבית 0:

טבלה 5.13
רישום בקרת פסיקה
אינדקס סיביות מַשְׁמָעוּת
0 מוגדר (מבוצע 1) על ידי זרימה תת-קרקעית של טיימר A
1 נקבע על ידי זרימה נמוכה של טיימר B
2 הגדר כאשר שעון השעה שווה להתראה
3 הגדר כאשר היציאה הטורית מלאה
4 מוגדר על ידי מכשיר חיצוני
5 לא בשימוש (עשה 0)
6 לא בשימוש (עשה 0)
7 מוגדר כאשר כל אחד מחמשת הביטים הראשונים מוגדר

כפי שניתן לראות מהטבלה, כל אחד מהמקורות המיידיים מיוצג על ידי אחד מחמשת הביטים הראשונים. לכן, כאשר אות ההפסקה מתקבל ב-µP, יש להפעיל את הקוד כדי לקרוא את התוכן של אוגר בקרת הפסיקות כדי לדעת את המקור המדויק של ההפרעה. כתובת ה-RAM עבור ICR של CIA #1 היא DC0D16. כתובת ה-RAM עבור ICR של CIA #2 היא DD0D16. כדי לקרוא (להחזיר) את התוכן של ICR של CIA #1 לצבר µP, הקלד את ההוראה הבאה:

LDA$DC0D

כדי לקרוא (להחזיר) את התוכן של ה-ICR של CIA #2 לצבר µP, הקלד את ההוראה הבאה:

LDA $DD0D

5.13 תוכנית רקע מונעת פסיקה

המקלדת בדרך כלל קוטעת את המיקרו-מעבד כל 1/60 שניה. תארו לעצמכם שתוכנית פועלת והיא מגיעה למצב לחכות למקש מהמקלדת לפני שתוכל להמשיך עם קטעי הקוד למטה. נניח שאם לא לוחצים על מקש מהמקלדת, התוכנית עושה רק לולאה קטנה, ממתינה למקש. תארו לעצמכם שהתוכנית פועלת ורק מצפה למפתח מהמקלדת מיד לאחר הוצאת ההפרעה במקלדת. בשלב זה, כל המחשב עוצר בעקיפין ואינו עושה דבר מלבד לולאת ההמתנה. תארו לעצמכם שמקש מקלדת נלחץ ממש לפני הגיליון הבא של ההפסקה הבאה במקלדת. זה אומר שהמחשב לא עשה כלום במשך כשישים שניה! זה הרבה זמן למחשב לא לעשות כלום, אפילו בימי קומודור-64. המחשב יכול היה לעשות משהו אחר בזמן הזה (משך הזמן). יש הרבה משכי זמן כאלה בתוכנית.

ניתן לכתוב תוכנית שנייה שתפעל בתקופות 'בטלה' כאלה. אומרים שתוכנית כזו פועלת ברקע התוכנית הראשית (או הראשונה). דרך קלה לעשות זאת היא פשוט לאלץ טיפול בפסיקת BRK שונה כאשר צפוי מפתח מהמקלדת.

מצביע להוראת BRK
במיקומים הרצופים של ה-RAM של הכתובות $0316 ו-$0317 נמצא המצביע (וקטור) לשגרת הוראות ה-BRK בפועל. מצביע ברירת המחדל מוצב שם כאשר המחשב מופעל על ידי מערכת ההפעלה ב-ROM. מצביע ברירת מחדל זה הוא כתובת שעדיין מצביעה על מטפל ברירת המחדל של הוראות BRK ב-OS ROM. המצביע הוא כתובת של 16 סיביות. הבית התחתון של המצביע ממוקם במיקום בתים של הכתובת $0306, והבית הגבוה יותר של המצביע ממוקם במיקום בתים $0317.

תוכנית שנייה יכולה להיכתב כך שכאשר המערכת 'בטלה', חלק מהקודים של התוכנית השנייה מבוצעים על ידי המערכת. המשמעות היא שהתוכנית השנייה צריכה להיות מורכבת מתתי שגרות. כאשר המערכת 'בטלה' שמחכה למפתח מהמקלדת, תתבצע תת שגרה הבאה לתוכנית השנייה. האינטראקציה האנושית עם המחשב איטית בהשוואה לפעולת יחידת המערכת.

קל לפתור את הבעיה הזו: בכל פעם שהמחשב צריך לחכות למפתח מהמקלדת, הכנס הוראת BRK בקוד והחלף את המצביע ב-$0316 (ו-0317$) במצביע של תת-השגרה הבאה של השני ( תוכנית מותאמת אישית). באופן זה, שתי התוכניות יפעלו במשך זמן שאינו ארוך בהרבה מזה של התוכנית הראשית שפועלת לבד.

5.14 הרכבה והידור

האסמבלר מחליף את כל התוויות בכתובות. תוכנית שפת assembly נכתבת בדרך כלל כדי להתחיל בכתובת מסוימת. התוצאה מהאסמבלר (לאחר ההרכבה) נקראת 'קוד האובייקט' עם הכל בבינארי. תוצאה זו היא קובץ ההפעלה אם הקובץ הוא תוכנית ולא מסמך. מסמך אינו בר הפעלה.

אפליקציה מורכבת מיותר מתוכנית אחת (שפת הרכבה). בדרך כלל יש תוכנית ראשית. אין לבלבל את המצב כאן עם המצב עבור תוכניות הרקע מונעות הפסקות. כל התוכניות כאן הן תוכניות קדמה, אבל יש תוכנית ראשונה או ראשית.

יש צורך במהדר במקום ב-assembler כאשר יש יותר מתוכנת חזית אחת. המהדר מרכיב כל אחת מהתוכניות לקוד אובייקט. עם זאת, תהיה בעיה: חלק מקטעי הקוד יהיו חופפים מכיוון שהתוכניות נכתבות כנראה על ידי אנשים שונים. הפתרון של המהדר הוא להזיז את כל התוכנות החופפות למעט הראשונה בשטח הזיכרון, כדי שהתוכניות לא יחפפו. כעת, כשמדובר באחסון משתנים, חלק מהכתובות המשתנות עדיין היו חופפות. הפתרון כאן הוא להחליף את הכתובות החופפות בכתובות החדשות (פרט לתוכנית הראשונה) כך שהן לא חופפות יותר. בדרך זו, התוכניות השונות יתאימו לחלקים (אזורים) השונים של הזיכרון.

עם כל זה, אפשר לשגרה אחת בתוכנית אחת לקרוא לשגרה בתוכנית אחרת. אז, המהדר מבצע את הקישור. קישור מתייחס לקיומה של כתובת ההתחלה של תת-שגרה בתוכנית אחת ואז קריאה לה בתוכנית אחרת; שניהם חלק מהיישום. שתי התוכניות צריכות להשתמש באותה כתובת לשם כך. התוצאה הסופית היא קוד אובייקט אחד גדול עם הכל בבינארי (סיביות).

5.15 שמירה, טעינה והרצה של תוכנית

שפת אסמבלר נכתבת בדרך כלל בתוכנית עורך כלשהי (שעשויה להיות מסופקת עם תוכנית האסמבלר). תוכנית העורך מציינת היכן התוכנית מתחילה ומסתיימת בזיכרון (RAM). שגרת Kernal SAVE של OS ROM של Commodore-64 יכולה לשמור תוכנית בזיכרון בדיסק. זה פשוט זורק את הקטע (בלוק) של הזיכרון שעשוי להכיל את קריאת ההוראות שלו לדיסק. רצוי להפריד את הוראת הקריאה ל-SAVE מהתוכנה הנשמרת, כך שכאשר התוכנית תועלה לזיכרון מהדיסק, היא לא תשמור את עצמה שוב בעת הפעלתה. טעינת תוכנית שפת assembly מהדיסק היא אתגר מסוג אחר מכיוון שתוכנית לא יכולה לטעון את עצמה.

תוכנית לא יכולה לטעון את עצמה מהדיסק למקום שבו היא מתחילה ומסתיימת ב-RAM. ה-Commodore-64 באותם ימים סופק בדרך כלל עם מתורגמן BASIC להפעלת תוכניות השפה BASIC. כאשר המכשיר (המחשב) מופעל, הוא מתיישב עם שורת הפקודה: READY. משם, ניתן להקליד את הפקודות או ההוראות הבסיסיות על ידי לחיצה על מקש 'Enter' לאחר ההקלדה. הפקודה BASIC (הוראה) לטעינת קובץ היא:

טען 'שם קובץ',8,1

הפקודה מתחילה במילה השמורה BASIC שהיא LOAD. זה מלווה ברווח ולאחר מכן את שם הקובץ במירכאות כפולות. אחריו מספר המכשיר 8 אשר לפניו פסיק. אחרי הכתובת המשנית של הדיסק שהיא 1, לפניה פסיק. עם קובץ כזה, כתובת ההתחלה של תוכנית שפת ה-Assembly נמצאת בכותרת של הקובץ בדיסק. כאשר ה-BASIC מסיים לטעון את התוכנית, מוחזרת כתובת ה-RAM האחרונה פלוס 1 של התוכנית. המילה 'מוחזרת' כאן פירושה שהבייט התחתון של הכתובת האחרונה פלוס 1 מיושם באוגר µP X, והבייט הגבוה יותר של הכתובת האחרונה פלוס 1 מיושם באוגר µP Y.

לאחר טעינת התוכנית, יש להפעיל אותה (להפעיל אותה). המשתמש בתוכנית צריך לדעת את כתובת ההתחלה לביצוע בזיכרון. שוב, יש צורך בתוכנית BASIC נוספת כאן. זו הפקודה SYS. לאחר ביצוע הפקודה SYS, תוכנית שפת ההרכבה תפעל (ותיעצר). בזמן הריצה, אם יש צורך בקלט כלשהו מהמקלדת, תוכנית שפת ההרכבה צריכה לציין זאת בפני המשתמש. לאחר שהמשתמש מקליד את הנתונים על המקלדת ולוחץ על מקש 'Enter', תוכנית שפת ההרכבה תמשיך לפעול באמצעות כניסת המקלדת ללא הפרעה של המתורגמן BASIC.

בהנחה שתחילת כתובת ה-RAM לביצוע (הריצה) עבור תוכנית ה-Assembly Language היא C12316, C123 מומר לבסיס עשר לפני השימוש בו עם הפקודה SYS. המרת C12316 לבסיס עשר היא כדלקמן:

אז, הפקודה BASIC SYS היא:

SYS 49443

5.16 אתחול עבור Commodore-64

האתחול של ה-Commodore-64 מורכב משני שלבים: שלב איפוס החומרה ושלב האתחול של מערכת ההפעלה. מערכת ההפעלה היא ה-Kernal ב-ROM (ולא בדיסק). יש קו איפוס (למעשה RES ) שמתחבר לפין ב-6502 µP, ולאותו שם פין בכל הספינות המיוחדות כגון CIA 1, CIA 2 ו-VIC II. בשלב האיפוס, עקב קו זה, כל הרגיסטרים ב-µP ובשבבים מיוחדים מאופסים ל-0 (אפס עבור כל סיביות). לאחר מכן, על ידי חומרת המיקרו-מעבד, מצביע המחסנית ואוגר מצב המעבד ניתנים עם הערכים ההתחלתיים שלהם במיקרו-מעבד. לאחר מכן ניתן מונה התוכנית עם הערך (הכתובת) במיקומים $FFFC ו-$FFFD. זכור שמונה התוכנית מכיל את הכתובת של ההוראה הבאה. התוכן (הכתובת) שמוחזק כאן הוא עבור תת-השגרה שמתחילה את אתחול התוכנה. הכל עד כה נעשה על ידי חומרת המיקרו-מעבד. בשלב זה לא נוגעים בכל הזיכרון. לאחר מכן מתחיל השלב הבא של האתחול.

האתחול מתבצע על ידי כמה שגרות במערכת ההפעלה ROM. אתחול פירושו לתת את ערכי ההתחלה או ברירת המחדל לכמה אוגרים בצ'יפים המיוחדים. אתחול מתחיל במתן ערכי ההתחלה או ברירת המחדל לכמה אוגרים בצ'יפים המיוחדים. IRQ , למשל, צריך להתחיל להנפיק כל 1/60 שניה. לכן, יש להגדיר את הטיימר המתאים שלו ב-CIA #1 לערך ברירת המחדל שלו.

לאחר מכן, ה-Kernal מבצע בדיקת זיכרון RAM. הוא בודק כל מיקום על ידי שליחת בתים למיקום וקריאתו בחזרה. אם יש הבדל, לפחות המיקום הזה גרוע. Kernal גם מזהה את החלק העליון של הזיכרון ואת החלק התחתון של הזיכרון ומגדירה את המצביעים המתאימים בעמוד 2. אם החלק העליון של הזיכרון הוא $DFFF, $FF מושם במיקום $0283 ו-$DF מושם במיקום $0284 בתים. גם ל-$0283 וגם ל-$0284 יש את התווית HIRAM. אם החלק התחתון של הזיכרון הוא $0800, $00 מושם במיקום $0281 ו$08 מושם במיקום $0282. גם ל-$0281 וגם ל-$0282 יש את התווית LORAM. מבחן ה-RAM מתחיל למעשה מ-$0300 לראש הזיכרון (RAM).

לבסוף, וקטורי הקלט/פלט (המצביעים) מוגדרים לערכי ברירת המחדל שלהם. מבחן ה-RAM מתחיל למעשה מ-$0300 לראש הזיכרון (RAM). המשמעות היא שעמוד 0, עמוד 1 ועמוד 2 מאותחלים. בעמוד 0, במיוחד, יש הרבה מצביעי OS ROM ובעמוד 2 יש הרבה מצביעי BASIC. מצביעים אלה מכונים משתנים. זכור שעמוד 1 הוא הערימה. המצביעים מכונים משתנים מכיוון שיש להם שמות (תוויות). בשלב זה, זיכרון המסך מנוקה עבור המסך (מוניטור). משמעות הדבר היא שליחת הקוד של $20 עבור שטח (שזה במקרה זהה ל-ASCII $20) למיקומי מסך 1000 RAM. לבסוף, ה-Kernal מפעיל את המתורגמן BASIC כדי להציג את שורת הפקודה BASIC שהיא READY בחלק העליון של הצג (מסך).

5.17 בעיות

מומלץ לקורא לפתור את כל הבעיות בפרק לפני המעבר לפרק הבא.

  1. כתוב קוד שפת assembly שהופך את כל הביטים של יציאת CIA #2 כפלט ויציאת CIA #2 B כקלט.
  2. כתוב קוד שפה 6502-assembly שמחכה למקש מקלדת עד ללחוץ עליו.
  3. כתוב תוכנית שפת 6502-assembly ששולחת את התו 'E' למסך Commodore-64.
  4. כתוב תוכנית שפת 6502-assembly שלוקחת תו מהמקלדת ושולחת אותו למסך Commodore-64, תוך התעלמות מקוד המפתח והתזמון.
  5. כתוב תוכנית שפת 6502-assembly שמקבלת בייט מהדיסקט של Commodore-64.
  6. כתוב תוכנית שפת 6502-assembly ששומרת קובץ בתקליטון Commodore-64.
  7. כתוב תוכנית שפת 6502-assembly אשר טוענת קובץ תוכנית מהדיסקט של Commodore-64 ומפעילה אותו.
  8. כתוב תוכנית שפת 6502-assembly ששולחת את ה-Byte 'E' (ASCII) למודם המחובר ליציאת המשתמש תואמת RS-232 של ה-Commodore-64.
  9. הסבירו כיצד מתבצעים ספירה ותזמון במחשב Commodore-64.
  10. הסבר כיצד יחידת המערכת Commodore-64 יכולה לזהות 10 מקורות שונים של בקשות פסיקה מיידית, כולל בקשות פסיקה שאינן ניתנות למסיכה.
  11. הסבר כיצד תוכנית רקע יכולה לרוץ עם תוכנית חזית במחשב Commodore-64.
  12. הסבר בקצרה כיצד ניתן להרכיב את תוכניות שפת ה-Assembly ליישום אחד עבור מחשב Commodore-64.
  13. הסבר בקצרה את תהליך האתחול של מחשב Commodore-64.