Fix pre-write for the language card

This is the same issue as the `MMU`, namely that `langcard.ts` would
deactivate writing to the language card if `prewrite` was reset.
However, it is totally possible to reset `prewrite` and leave writing
enabled, as shown my Sather in _Understanding the Apple II_, table
5.4, p. 5-30. See the previous commit for an example.

This change also adds a test for the `LanguageCard` class.
This commit is contained in:
Ian Flanigan 2023-07-07 11:39:45 +02:00
parent d6d67b2a44
commit e56c307f4b
No known key found for this signature in database
GPG Key ID: 035F657DAE4AE7EC
2 changed files with 57 additions and 4 deletions

View File

@ -1,5 +1,5 @@
import RAM, { RAMState } from '../ram';
import { debug } from '../util';
// import { debug } from '../util';
import { Card, Memory, byte, Restorable } from '../types';
export interface LanguageCardState {
@ -30,7 +30,7 @@ export default class LanguageCard implements Card, Restorable<LanguageCardState>
private write2: Memory;
constructor(private rom: Memory) {
debug('Language card');
// debug('Language card');
this.bank1 = new RAM(0xd0, 0xdf);
this.bank2 = new RAM(0xd0, 0xdf);
@ -88,9 +88,11 @@ export default class LanguageCard implements Card, Restorable<LanguageCardState>
let bankStr;
let rwStr;
if (writeSwitch) { // $C081, $C083, $C089, $C08B
if (writeSwitch) { // 0xC081, 0xC083
if (readMode) {
this._writebsr = this._prewrite;
if (this._prewrite) {
this._writebsr = true;
}
}
this._prewrite = readMode;

View File

@ -0,0 +1,51 @@
import LanguageCard from '../../../js/cards/langcard';
import Apple2ROM from '../../../js/roms/system/fpbasic';
describe('Language Card', () => {
it('is constructable', () => {
const langCard = new LanguageCard(new Apple2ROM());
expect(langCard).not.toBeNull();
});
it('requires prewrite to write to bank1', () => {
const langCard = new LanguageCard(new Apple2ROM());
// From https://github.com/whscullin/apple2js/issues/187
// Action descriptions from Sather, Table 5.5, p. 5-24, UtAIIe:
langCard.ioSwitch(0x8b); // WRTCOUNT = WRTCOUNT + 1, READ ENABLE
langCard.ioSwitch(0x8b); // WRTCOUNT = WRTCOUNT + 1, READ ENABLE (write enabled)
langCard.ioSwitch(0x89, 0x00); // WRTCOUNT = 0, READ DISABLE (write still enabled)
langCard.ioSwitch(0x89); // WRTCOUNT = WRITCOUNT + 1, READ DISABLE (write still enabled)
langCard.write(0xd0, 0x00, 0xa1);
langCard.ioSwitch(0x8b); // WRTCOUNT = WRTCOUNT + 1, READ ENABLE (write still enabled)
expect(langCard.read(0xd0, 0x00)).toBe(0xa1);
});
it('prewrite is reset on write access before write', () => {
const langCard = new LanguageCard(new Apple2ROM());
// Action descriptions from Sather, Table 5.5, p. 5-24, UtAIIe:
langCard.ioSwitch(0x89, 0x00); // WRTCOUNT = 0, READ DISABLE
langCard.ioSwitch(0x8b); // WRTCOUNT = WRTCOUNT + 1, READ ENABLE (write not enabled yet)
langCard.ioSwitch(0x8b, 0x00); // WRTCOUNT = 0, READ ENABLE (write still not enabled)
const oldValue = langCard.read(0xd0, 0x00);
langCard.write(0xd0, 0x00, 0xa1); // writes to the void
expect(langCard.read(0xd0, 0x00)).toBe(oldValue); // reads old value
});
it('write stays active with overzealous switching', () => {
const langCard = new LanguageCard(new Apple2ROM());
// Action descriptions from Sather, Table 5.5, p. 5-24, UtAIIe:
langCard.ioSwitch(0x8b); // WRTCOUNT = WRTCOUNT + 1, READ ENABLE
langCard.ioSwitch(0x8b); // WRTCOUNT = WRTCOUNT + 1, READ ENABLE (write enabled)
langCard.ioSwitch(0x8b); // WRTCOUNT = WRTCOUNT + 1, READ ENABLE (write enabled)
langCard.ioSwitch(0x8b); // WRTCOUNT = WRTCOUNT + 1, READ ENABLE (write enabled)
langCard.write(0xd0, 0x00, 0xa1);
langCard.ioSwitch(0x8b); // WRTCOUNT = WRTCOUNT + 1, READ ENABLE (write still enabled)
expect(langCard.read(0xd0, 0x00)).toBe(0xa1);
});
});