mirror of
https://github.com/cmosher01/Epple-II.git
synced 2024-12-29 00:31:40 +00:00
RAM config; remove obsolete nib paths from config files
This commit is contained in:
parent
0183c5304f
commit
e8cdb8975e
@ -9,3 +9,9 @@
|
|||||||
import motherboard rom 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
import motherboard rom 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
||||||
import motherboard rom 2425 $(PREFIX)lib/apple2/system/a2/other.a65
|
import motherboard rom 2425 $(PREFIX)lib/apple2/system/a2/other.a65
|
||||||
import motherboard rom 2800 $(PREFIX)lib/apple2/system/a2/monitor.a65
|
import motherboard rom 2800 $(PREFIX)lib/apple2/system/a2/monitor.a65
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 4K RAM
|
||||||
|
motherboard ram C 4K 4K 4K 4K 4K 4K 4K 4K
|
||||||
|
motherboard strap C 4K 0000
|
||||||
|
@ -9,6 +9,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 48K RAM
|
||||||
|
motherboard ram E 16K
|
||||||
|
motherboard ram D 16K
|
||||||
|
motherboard ram C 16K
|
||||||
|
motherboard strap E 16K 8000
|
||||||
|
motherboard strap D 16K 4000
|
||||||
|
motherboard strap C 16K 0000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Integer BASIC and old Monitor ROMs
|
# Integer BASIC and old Monitor ROMs
|
||||||
import motherboard rom 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
import motherboard rom 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
||||||
import motherboard rom 2425 $(PREFIX)lib/apple2/system/a2/other.a65
|
import motherboard rom 2425 $(PREFIX)lib/apple2/system/a2/other.a65
|
||||||
@ -21,4 +31,4 @@ slot 6 disk13
|
|||||||
import slot 6 rom 0 $(PREFIX)lib/apple2/dos/13sector/disk2.a65
|
import slot 6 rom 0 $(PREFIX)lib/apple2/dos/13sector/disk2.a65
|
||||||
|
|
||||||
# Insert DOS 3.1 System Master disk into drive 1
|
# Insert DOS 3.1 System Master disk into drive 1
|
||||||
load slot 6 drive 1 $(PREFIX)lib/apple2/dos/13sector/dos310/clean31sysmas_stock_rawdos.nib
|
#load slot 6 drive 1 $(PREFIX)lib/apple2/dos/13sector/dos310/clean31sysmas_stock_rawdos.dsk.woz
|
||||||
|
@ -9,6 +9,17 @@
|
|||||||
# indicator on the language card line turning on or off.
|
# indicator on the language card line turning on or off.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 48K RAM
|
||||||
|
motherboard ram E 16K
|
||||||
|
motherboard ram D 16K
|
||||||
|
motherboard ram C 16K
|
||||||
|
motherboard strap E 16K 8000
|
||||||
|
motherboard strap D 16K 4000
|
||||||
|
motherboard strap C 16K 0000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Integer BASIC and old Monitor ROMs
|
# Integer BASIC and old Monitor ROMs
|
||||||
import motherboard rom 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
import motherboard rom 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
||||||
import motherboard rom 2425 $(PREFIX)lib/apple2/system/a2/other.a65
|
import motherboard rom 2425 $(PREFIX)lib/apple2/system/a2/other.a65
|
||||||
@ -26,4 +37,4 @@ slot 6 disk
|
|||||||
import slot 6 rom 0 $(PREFIX)lib/apple2/dos/16sector/disk2.a65
|
import slot 6 rom 0 $(PREFIX)lib/apple2/dos/16sector/disk2.a65
|
||||||
|
|
||||||
# Insert DOS 3.3 System Master disk (original version) in drive 1
|
# Insert DOS 3.3 System Master disk (original version) in drive 1
|
||||||
load slot 6 drive 1 $(PREFIX)lib/apple2/dos/16sector/dos330/clean330sysmas.nib
|
#load slot 6 drive 1 $(PREFIX)lib/apple2/dos/16sector/dos330/clean330sysmas.dsk.woz
|
||||||
|
@ -9,6 +9,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 48K RAM
|
||||||
|
motherboard ram E 16K
|
||||||
|
motherboard ram D 16K
|
||||||
|
motherboard ram C 16K
|
||||||
|
motherboard strap E 16K 8000
|
||||||
|
motherboard strap D 16K 4000
|
||||||
|
motherboard strap C 16K 0000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Integer BASIC and old Monitor ROMs
|
# Integer BASIC and old Monitor ROMs
|
||||||
import motherboard rom 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
import motherboard rom 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
||||||
import motherboard rom 2425 $(PREFIX)lib/apple2/system/a2/other.a65
|
import motherboard rom 2425 $(PREFIX)lib/apple2/system/a2/other.a65
|
||||||
@ -48,7 +58,7 @@ import slot 4 rom 0 $(PREFIX)lib/epple2/cards/clock.a65
|
|||||||
slot 5 disk13
|
slot 5 disk13
|
||||||
import slot 5 rom 0 $(PREFIX)lib/apple2/dos/13sector/disk2.a65
|
import slot 5 rom 0 $(PREFIX)lib/apple2/dos/13sector/disk2.a65
|
||||||
# Insert the DOS 3.1 System Master disk into drive 1 of slot 5
|
# Insert the DOS 3.1 System Master disk into drive 1 of slot 5
|
||||||
load slot 5 drive 1 $(PREFIX)lib/apple2/dos/13sector/dos310/clean31sysmas_stock_rawdos.nib
|
#load slot 5 drive 1 $(PREFIX)lib/apple2/dos/13sector/dos310/clean31sysmas_stock_rawdos.dsk.woz
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -57,7 +67,7 @@ load slot 5 drive 1 $(PREFIX)lib/apple2/dos/13sector/dos310/clean31sysmas_stock_
|
|||||||
slot 6 disk
|
slot 6 disk
|
||||||
import slot 6 rom 0 $(PREFIX)lib/apple2/dos/16sector/disk2.a65
|
import slot 6 rom 0 $(PREFIX)lib/apple2/dos/16sector/disk2.a65
|
||||||
# Insert the DOS 3.3 System Master disk (original version) into slot 6
|
# Insert the DOS 3.3 System Master disk (original version) into slot 6
|
||||||
load slot 6 drive 1 $(PREFIX)lib/apple2/dos/16sector/dos330/clean330sysmas.nib
|
#load slot 6 drive 1 $(PREFIX)lib/apple2/dos/16sector/dos330/clean330sysmas.dsk.woz
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,3 +8,9 @@
|
|||||||
|
|
||||||
import motherboard rom 0000 $(PREFIX)lib/apple2/system/a2p/applesoft.a65
|
import motherboard rom 0000 $(PREFIX)lib/apple2/system/a2p/applesoft.a65
|
||||||
import motherboard rom 2800 $(PREFIX)lib/apple2/system/a2p/monitor.a65
|
import motherboard rom 2800 $(PREFIX)lib/apple2/system/a2p/monitor.a65
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 4K RAM
|
||||||
|
motherboard ram C 4K 4K 4K 4K 4K 4K 4K 4K
|
||||||
|
motherboard strap C 4K 0000
|
||||||
|
@ -9,6 +9,16 @@
|
|||||||
# indicator on the language card line turning on or off.
|
# indicator on the language card line turning on or off.
|
||||||
|
|
||||||
|
|
||||||
|
# 48K RAM
|
||||||
|
motherboard ram E 16K
|
||||||
|
motherboard ram D 16K
|
||||||
|
motherboard ram C 16K
|
||||||
|
motherboard strap E 16K 8000
|
||||||
|
motherboard strap D 16K 4000
|
||||||
|
motherboard strap C 16K 0000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Applesoft BASIC and Autostart Monitor ROMs
|
# Applesoft BASIC and Autostart Monitor ROMs
|
||||||
import motherboard rom 0000 $(PREFIX)lib/apple2/system/a2p/applesoft.a65
|
import motherboard rom 0000 $(PREFIX)lib/apple2/system/a2p/applesoft.a65
|
||||||
import motherboard rom 2800 $(PREFIX)lib/apple2/system/a2p/monitor.a65
|
import motherboard rom 2800 $(PREFIX)lib/apple2/system/a2p/monitor.a65
|
||||||
@ -25,4 +35,4 @@ slot 6 disk
|
|||||||
import slot 6 rom 0 $(PREFIX)lib/apple2/dos/16sector/disk2.a65
|
import slot 6 rom 0 $(PREFIX)lib/apple2/dos/16sector/disk2.a65
|
||||||
|
|
||||||
# Insert DOS 3.3 System Master disk (original version) in drive 1
|
# Insert DOS 3.3 System Master disk (original version) in drive 1
|
||||||
load slot 6 drive 1 $(PREFIX)lib/apple2/dos/16sector/disks/dos330/clean330sysmas.nib
|
#load slot 6 drive 1 $(PREFIX)lib/apple2/dos/16sector/disks/dos330/clean330sysmas.dsk.woz
|
||||||
|
@ -9,6 +9,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 48K RAM
|
||||||
|
motherboard ram E 16K
|
||||||
|
motherboard ram D 16K
|
||||||
|
motherboard ram C 16K
|
||||||
|
motherboard strap E 16K 8000
|
||||||
|
motherboard strap D 16K 4000
|
||||||
|
motherboard strap C 16K 0000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Applesoft BASIC and Autostart Monitor ROMs
|
# Applesoft BASIC and Autostart Monitor ROMs
|
||||||
import motherboard rom 0000 $(PREFIX)lib/apple2/system/a2p/applesoft.a65
|
import motherboard rom 0000 $(PREFIX)lib/apple2/system/a2p/applesoft.a65
|
||||||
import motherboard rom 2800 $(PREFIX)lib/apple2/system/a2p/monitor.a65
|
import motherboard rom 2800 $(PREFIX)lib/apple2/system/a2p/monitor.a65
|
||||||
@ -47,7 +57,7 @@ import slot 4 rom 0 $(PREFIX)lib/epple2/cards/clock.a65
|
|||||||
slot 5 disk13
|
slot 5 disk13
|
||||||
import slot 5 rom 0 $(PREFIX)lib/apple2/dos/13sector/disk2.a65
|
import slot 5 rom 0 $(PREFIX)lib/apple2/dos/13sector/disk2.a65
|
||||||
# Insert the DOS 3.1 System Master disk into drive 1 of slot 5
|
# Insert the DOS 3.1 System Master disk into drive 1 of slot 5
|
||||||
load slot 5 drive 1 $(PREFIX)lib/apple2/dos/13sector/dos310/clean31sysmas_stock_rawdos.nib
|
#load slot 5 drive 1 $(PREFIX)lib/apple2/dos/13sector/dos310/clean31sysmas_stock_rawdos.dsk.woz
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -56,7 +66,7 @@ load slot 5 drive 1 $(PREFIX)lib/apple2/dos/13sector/dos310/clean31sysmas_stock_
|
|||||||
slot 6 disk
|
slot 6 disk
|
||||||
import slot 6 rom 0 $(PREFIX)lib/apple2/dos/16sector/disk2.a65
|
import slot 6 rom 0 $(PREFIX)lib/apple2/dos/16sector/disk2.a65
|
||||||
# Insert the DOS 3.3 System Master disk (original version) into slot 6
|
# Insert the DOS 3.3 System Master disk (original version) into slot 6
|
||||||
load slot 6 drive 1 $(PREFIX)lib/apple2/dos/16sector/dos330/clean330sysmas.nib
|
#load slot 6 drive 1 $(PREFIX)lib/apple2/dos/16sector/dos330/clean330sysmas.dsk.woz
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,6 +11,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# standard 48K RAM
|
||||||
|
motherboard ram E 16K
|
||||||
|
motherboard ram D 16K
|
||||||
|
motherboard ram C 16K
|
||||||
|
motherboard strap E 16K 8000
|
||||||
|
motherboard strap D 16K 4000
|
||||||
|
motherboard strap C 16K 0000
|
||||||
|
|
||||||
# Demo system ROM for the emulator. This is only to allow the
|
# Demo system ROM for the emulator. This is only to allow the
|
||||||
# emulator to do something useful when there are no real Apple ROM
|
# emulator to do something useful when there are no real Apple ROM
|
||||||
# images provided.
|
# images provided.
|
||||||
@ -40,11 +48,11 @@ import slot 4 rom 0 $(PREFIX)lib/epple2/cards/clock.a65
|
|||||||
|
|
||||||
#slot 5 disk13
|
#slot 5 disk13
|
||||||
#import slot 5 rom 0 $(PREFIX)lib/apple2/dos/13sector/disk2.a65
|
#import slot 5 rom 0 $(PREFIX)lib/apple2/dos/13sector/disk2.a65
|
||||||
#load slot 5 drive 1 $(PREFIX)lib/apple2/dos/13sector/dos310/clean31sysmas_stock_rawdos.nib
|
#load slot 5 drive 1 $(PREFIX)lib/apple2/dos/13sector/dos310/clean31sysmas_stock_rawdos.dsk.woz
|
||||||
|
|
||||||
#slot 6 disk
|
#slot 6 disk
|
||||||
#import slot 6 rom 0 $(PREFIX)lib/apple2/dos/16sector/disk2.a65
|
#import slot 6 rom 0 $(PREFIX)lib/apple2/dos/16sector/disk2.a65
|
||||||
#load slot 6 drive 1 $(PREFIX)lib/apple2/dos/16sector/dos330/clean330sysmas.nib
|
#load slot 6 drive 1 $(PREFIX)lib/apple2/dos/16sector/dos330/clean330sysmas.dsk.woz
|
||||||
|
|
||||||
#slot 7 firmware
|
#slot 7 firmware
|
||||||
#import slot 7 rombank 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
#import slot 7 rombank 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
||||||
|
@ -10,6 +10,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Use an original, revision zero, motherboard
|
||||||
|
revision 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Load Integer BASIC and old Monitor ROMs
|
# Load Integer BASIC and old Monitor ROMs
|
||||||
import motherboard rom 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
import motherboard rom 1000 $(PREFIX)lib/apple2/system/a2/intbasic.a65
|
||||||
import motherboard rom 2425 $(PREFIX)lib/apple2/system/a2/other.a65
|
import motherboard rom 2425 $(PREFIX)lib/apple2/system/a2/other.a65
|
||||||
@ -17,5 +22,6 @@ import motherboard rom 2800 $(PREFIX)lib/apple2/system/a2/monitor.a65
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Use an original, revision zero, motherboard
|
# 4K RAM
|
||||||
revision 0
|
motherboard ram C 4K 4K 4K 4K 4K 4K 4K 4K
|
||||||
|
motherboard strap C 4K 0000
|
||||||
|
@ -2,7 +2,7 @@ anchor:commands[]
|
|||||||
|
|
||||||
=== Commands
|
=== Commands
|
||||||
|
|
||||||
+<<slot>> <<import>> <<load>> <<unload>> <<save>> <<cassette>> <<revision>>+
|
+<<slot>> <<motherboard>> <<import>> <<load>> <<unload>> <<save>> <<cassette>> <<revision>>+
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +45,58 @@ The emulated Apple should be _powered off_ before inserting or removing cards.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
anchor:motherboard[]
|
||||||
|
|
||||||
|
==== motherboard
|
||||||
|
|
||||||
|
The +motherboard+ command configures the emulated Apple's motherboard RAM chips and strapping block.
|
||||||
|
|
||||||
|
--------
|
||||||
|
motherboard ram {C|D|E} { 4K | 4096 | 16K | 4116 | - } [...up to 8]
|
||||||
|
motherboard strap {C|D|E} { 4K | 16K } <base>
|
||||||
|
--------
|
||||||
|
|
||||||
|
The RAM configuration lines represent the rows of chips on the motherboard. The motherboard labels the
|
||||||
|
rows as C, D, and E. Each row has 8 chips, one per bit in a byte. The Apple ][ accepts 4K or 16K chips.
|
||||||
|
You use the +ram+ command to insert (or remove) chips from the sockets.
|
||||||
|
You configure each row's address range by using a "strapping block" on the original Apple. In the
|
||||||
|
emulator, use the +strap+ command to perform this function. You should strap 4K rows to a 4K range
|
||||||
|
of RAM. You should always assign some RAM to the zero address.
|
||||||
|
|
||||||
|
For more information about RAM configuration, see
|
||||||
|
https://archive.org/details/Apple_II_Reference_Manual_1979_Apple/page/n79[Christopher Espinosa, Apple II Reference Manual
|
||||||
|
(Cupertino, Calif.: Apple Computer, 1978), pp. 70-72].
|
||||||
|
|
||||||
|
Example of normal 48K RAM configuration:
|
||||||
|
--------
|
||||||
|
ram e 16K
|
||||||
|
strap e 16K 8000
|
||||||
|
ram d 16K
|
||||||
|
strap d 16K 4000
|
||||||
|
ram c 16K
|
||||||
|
strap c 16K 0000
|
||||||
|
--------
|
||||||
|
|
||||||
|
Example of 4K, showing how you could specify each chip:
|
||||||
|
--------
|
||||||
|
ram e - - - - - - - -
|
||||||
|
ram d - - - - - - - -
|
||||||
|
ram c 4K 4K 4K 4K 4K 4K 4K 4K
|
||||||
|
strap c 4K 0000
|
||||||
|
--------
|
||||||
|
|
||||||
|
Example of 4K at zero address, and 8K at HI-RES page one:
|
||||||
|
--------
|
||||||
|
ram e 4K
|
||||||
|
strap e 4K 3000
|
||||||
|
ram d 4K
|
||||||
|
strap d 4K 2000
|
||||||
|
ram c 4K
|
||||||
|
strap c 4K 0000
|
||||||
|
--------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
anchor:import[]
|
anchor:import[]
|
||||||
|
|
||||||
==== import
|
==== import
|
||||||
@ -53,7 +105,7 @@ The +import+ command imports a binary image file into the emulated Apple's memor
|
|||||||
|
|
||||||
--------
|
--------
|
||||||
import slot <slot> { rom | rom7 | rombank } <base> <file-path>
|
import slot <slot> { rom | rom7 | rombank } <base> <file-path>
|
||||||
import motherboard { rom | ram } <base> <file-path>
|
import motherboard rom <base> <file-path>
|
||||||
--------
|
--------
|
||||||
|
|
||||||
+<slot>+ Slot number, 0 through 7, of peripheral card to import the binary image into.
|
+<slot>+ Slot number, 0 through 7, of peripheral card to import the binary image into.
|
||||||
@ -63,17 +115,16 @@ import motherboard { rom | ram } <base> <file-path>
|
|||||||
+<file-path>+ Path of the binary image to import.
|
+<file-path>+ Path of the binary image to import.
|
||||||
|
|
||||||
The +import+ command reads the binary image byte-for-byte from the given file-path
|
The +import+ command reads the binary image byte-for-byte from the given file-path
|
||||||
into an area of memory in the emulated Apple. You can load into either the motherboard or
|
into an area of ROM in the emulated Apple. You can load into either the motherboard or
|
||||||
a card in one of the slots. For the motherboard, you choose the RAM or ROM area. For a card
|
a card in one of the slots. For a card in a slot, you can choose either the normal ROM,
|
||||||
in a slot, you can choose either the normal ROM, the bank-switched ROM, or the so-called
|
the bank-switched ROM, or the so-called ``seventh ROM'' area.
|
||||||
``seventh ROM'' area.
|
|
||||||
|
|
||||||
You also have to specify the base address within the specific memory
|
You also have to specify the base address within the specific memory
|
||||||
area at which the image file will be loaded. Note that the base address is specified as the offset
|
area at which the image file will be loaded. Note that the base address is specified as the offset
|
||||||
within the specific memory area, and not necessarily as the actual memory address as seen
|
within the specific memory area, and not necessarily as the actual memory address as seen
|
||||||
by the Apple. So for motherboard ROM, for example, specifying a base as 2DED will cause the
|
by the Apple. So for motherboard ROM, for example, specifying a base as 2DED will cause the
|
||||||
image to be loaded at offset 2DED in the ROM, which will be addressed by the Apple at
|
image to be loaded at offset $2DED in the ROM, which will be addressed by the Apple at
|
||||||
memory address $FDED (because motherboard ROM ``starts'' at address $D000).
|
memory address $FDED, because motherboard ROM ``starts'' at address $D000, and $D000 + $2DED = $FDED.
|
||||||
|
|
||||||
For peripheral cards, the ROM will be seen at locations $Cs00-$CsFF, where s is the slot
|
For peripheral cards, the ROM will be seen at locations $Cs00-$CsFF, where s is the slot
|
||||||
number (1 through 7). The ``seventh ROM'' can be seen as locations $C800-$CFFF; Jim Sather
|
number (1 through 7). The ``seventh ROM'' can be seen as locations $C800-$CFFF; Jim Sather
|
||||||
|
@ -16,7 +16,9 @@ clipboardhandler.cpp clockcard.cpp \
|
|||||||
configep2.cpp cpu.cpp diskcontroller.cpp drive.cpp drivemotor.cpp \
|
configep2.cpp cpu.cpp diskcontroller.cpp drive.cpp drivemotor.cpp \
|
||||||
emptyslot.cpp emulator.cpp firmwarecard.cpp gui.cpp hypermode.cpp \
|
emptyslot.cpp emulator.cpp firmwarecard.cpp gui.cpp hypermode.cpp \
|
||||||
keyboard.cpp keyboardbuffermode.cpp languagecard.cpp filterchroma.cpp \
|
keyboard.cpp keyboardbuffermode.cpp languagecard.cpp filterchroma.cpp \
|
||||||
filterluma.cpp lss.cpp main.cpp memory.cpp paddlebuttonstates.cpp \
|
filterluma.cpp lss.cpp main.cpp memory.cpp \
|
||||||
|
memorychip.cpp memoryrow.cpp memorystrapping.cpp memoryrandomaccess.cpp \
|
||||||
|
paddlebuttonstates.cpp \
|
||||||
paddles.cpp picturegenerator.cpp powerupreset.cpp raminitializer.cpp \
|
paddles.cpp picturegenerator.cpp powerupreset.cpp raminitializer.cpp \
|
||||||
screenimage.cpp slots.cpp speakerclicker.cpp standardin.cpp \
|
screenimage.cpp slots.cpp speakerclicker.cpp standardin.cpp \
|
||||||
standardinproducer.cpp standardout.cpp steppermotor.cpp textcharacters.cpp \
|
standardinproducer.cpp standardout.cpp steppermotor.cpp textcharacters.cpp \
|
||||||
@ -31,7 +33,9 @@ card.h cassette.h cassettein.h cassetteout.h \
|
|||||||
clipboardhandler.h clockcard.h configep2.h cpu.h \
|
clipboardhandler.h clockcard.h configep2.h cpu.h \
|
||||||
diskcontroller.h drive.h drivemotor.h e2const.h emptyslot.h emulator.h firmwarecard.h font3x5.h gui.h \
|
diskcontroller.h drive.h drivemotor.h e2const.h emptyslot.h emulator.h firmwarecard.h font3x5.h gui.h \
|
||||||
hypermode.h keyboardbuffermode.h keyboard.h languagecard.h filterchroma.h \
|
hypermode.h keyboardbuffermode.h keyboard.h languagecard.h filterchroma.h \
|
||||||
filterluma.h lss.h memory.h paddlebuttonstates.h paddles.h picturegenerator.h \
|
filterluma.h lss.h memory.h \
|
||||||
|
memorychip.h memoryrow.h memorystrapping.h memoryrandomaccess.h \
|
||||||
|
paddlebuttonstates.h paddles.h picturegenerator.h \
|
||||||
powerupreset.h raminitializer.h screenimage.h slots.h speakerclicker.h \
|
powerupreset.h raminitializer.h screenimage.h slots.h speakerclicker.h \
|
||||||
standardin.h standardinproducer.h standardout.h steppermotor.h \
|
standardin.h standardinproducer.h standardout.h steppermotor.h \
|
||||||
textcharacterimages.h textcharacters.h timable.h util.h \
|
textcharacterimages.h textcharacters.h timable.h util.h \
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "addressbus.h"
|
#include "addressbus.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "memoryrandomaccess.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "videomode.h"
|
#include "videomode.h"
|
||||||
#include "paddles.h"
|
#include "paddles.h"
|
||||||
@ -26,7 +27,7 @@
|
|||||||
#include "cassetteout.h"
|
#include "cassetteout.h"
|
||||||
#include "slots.h"
|
#include "slots.h"
|
||||||
|
|
||||||
AddressBus::AddressBus(ScreenImage& gui, int& revision, Memory& ram, Memory& rom, Keyboard& kbd, VideoMode& vid, Paddles& paddles, PaddleButtonStates& paddleButtonStates, SpeakerClicker& speaker, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Slots& slts):
|
AddressBus::AddressBus(ScreenImage& gui, int& revision, MemoryRandomAccess& ram, Memory& rom, Keyboard& kbd, VideoMode& vid, Paddles& paddles, PaddleButtonStates& paddleButtonStates, SpeakerClicker& speaker, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Slots& slts):
|
||||||
gui(gui), revision(revision), ram(ram), rom(rom), kbd(kbd), vid(vid), paddles(paddles), paddleButtonStates(paddleButtonStates), speaker(speaker), cassetteIn(cassetteIn), cassetteOut(cassetteOut), slts(slts)
|
gui(gui), revision(revision), ram(ram), rom(rom), kbd(kbd), vid(vid), paddles(paddles), paddleButtonStates(paddleButtonStates), speaker(speaker), cassetteIn(cassetteIn), cassetteOut(cassetteOut), slts(slts)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
class ScreenImage;
|
class ScreenImage;
|
||||||
class Memory;
|
class Memory;
|
||||||
|
class MemoryRandomAccess;
|
||||||
class Keyboard;
|
class Keyboard;
|
||||||
class VideoMode;
|
class VideoMode;
|
||||||
class Paddles;
|
class Paddles;
|
||||||
@ -33,7 +34,7 @@ class AddressBus {
|
|||||||
private:
|
private:
|
||||||
ScreenImage& gui;
|
ScreenImage& gui;
|
||||||
int& revision;
|
int& revision;
|
||||||
Memory& ram;
|
MemoryRandomAccess& ram;
|
||||||
Memory& rom;
|
Memory& rom;
|
||||||
Keyboard& kbd;
|
Keyboard& kbd;
|
||||||
VideoMode& vid;
|
VideoMode& vid;
|
||||||
@ -47,7 +48,7 @@ class AddressBus {
|
|||||||
unsigned char data; // this emulates the (floating) data bus
|
unsigned char data; // this emulates the (floating) data bus
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AddressBus(ScreenImage& gui, int& revision, Memory& ram, Memory& rom, Keyboard& kbd, VideoMode& vid, Paddles& paddles, PaddleButtonStates& paddleButtonStates, SpeakerClicker& speaker, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Slots& slts);
|
AddressBus(ScreenImage& gui, int& revision, MemoryRandomAccess& ram, Memory& rom, Keyboard& kbd, VideoMode& vid, Paddles& paddles, PaddleButtonStates& paddleButtonStates, SpeakerClicker& speaker, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Slots& slts);
|
||||||
~AddressBus();
|
~AddressBus();
|
||||||
|
|
||||||
unsigned char read(const unsigned short address);
|
unsigned char read(const unsigned short address);
|
||||||
|
@ -42,7 +42,7 @@ Apple2::Apple2(KeypressQueue& keypresses, PaddleButtonStates& paddleButtonStates
|
|||||||
slts(gui),
|
slts(gui),
|
||||||
kbd(keypresses,fhyper,buffered),
|
kbd(keypresses,fhyper,buffered),
|
||||||
rom(AddressBus::MOTHERBOARD_ROM_SIZ),
|
rom(AddressBus::MOTHERBOARD_ROM_SIZ),
|
||||||
ram(AddressBus::MOTHERBOARD_RAM_SIZ),
|
ram(revision),
|
||||||
cassetteIn(gui),
|
cassetteIn(gui),
|
||||||
cassetteOut(gui),
|
cassetteOut(gui),
|
||||||
addressBus(gui,revision,ram,rom,kbd,videoMode,paddles,paddleButtonStates,speaker,cassetteIn,cassetteOut,slts),
|
addressBus(gui,revision,ram,rom,kbd,videoMode,paddles,paddleButtonStates,speaker,cassetteIn,cassetteOut,slts),
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "addressbus.h"
|
#include "addressbus.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "memoryrandomaccess.h"
|
||||||
#include "picturegenerator.h"
|
#include "picturegenerator.h"
|
||||||
#include "textcharacters.h"
|
#include "textcharacters.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
@ -51,7 +52,7 @@ class Apple2 : public Timable
|
|||||||
Paddles paddles;
|
Paddles paddles;
|
||||||
SpeakerClicker speaker;
|
SpeakerClicker speaker;
|
||||||
Memory rom;
|
Memory rom;
|
||||||
Memory ram;
|
MemoryRandomAccess ram;
|
||||||
CassetteIn cassetteIn;
|
CassetteIn cassetteIn;
|
||||||
CassetteOut cassetteOut;
|
CassetteOut cassetteOut;
|
||||||
AddressBus addressBus;
|
AddressBus addressBus;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "configep2.h"
|
#include "configep2.h"
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "memoryrandomaccess.h"
|
||||||
#include "slots.h"
|
#include "slots.h"
|
||||||
#include "diskcontroller.h"
|
#include "diskcontroller.h"
|
||||||
#include "languagecard.h"
|
#include "languagecard.h"
|
||||||
@ -36,6 +37,34 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
|
||||||
|
#define K 1024u
|
||||||
|
|
||||||
|
static std::uint16_t chip_size(const std::string &chip_model) {
|
||||||
|
if (chip_model == "4K") {
|
||||||
|
return 4u*K;
|
||||||
|
}
|
||||||
|
if (chip_model == "16K") {
|
||||||
|
return 16u*K;
|
||||||
|
}
|
||||||
|
if (chip_model == "-") {
|
||||||
|
return 0u;
|
||||||
|
}
|
||||||
|
throw ConfigException("unrecognized RAM chip model");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::uint16_t memory_block_size(const std::string &block_size) {
|
||||||
|
if (block_size == "4K") {
|
||||||
|
return 4u*K;
|
||||||
|
}
|
||||||
|
if (block_size == "16K") {
|
||||||
|
return 16u*K;
|
||||||
|
}
|
||||||
|
throw ConfigException("invalid RAM strapping block size (must be 4K or 16K)");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char Config::disk_mask(0);
|
unsigned char Config::disk_mask(0);
|
||||||
|
|
||||||
Config::Config(const std::string& file_path):
|
Config::Config(const std::string& file_path):
|
||||||
@ -75,7 +104,7 @@ static void trim(std::string& str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::parse(Memory& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut)
|
void Config::parse(MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut)
|
||||||
{
|
{
|
||||||
std::ifstream* pConfig;
|
std::ifstream* pConfig;
|
||||||
|
|
||||||
@ -154,7 +183,7 @@ void Config::parse(Memory& ram, Memory& rom, Slots& slts, int& revision, ScreenI
|
|||||||
|
|
||||||
// TODO: make sure there is no more than ONE stdin and/or ONE stdout card
|
// TODO: make sure there is no more than ONE stdin and/or ONE stdout card
|
||||||
}
|
}
|
||||||
void Config::parseLine(const std::string& line, Memory& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut)
|
void Config::parseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -166,7 +195,7 @@ void Config::parseLine(const std::string& line, Memory& ram, Memory& rom, Slots&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::tryParseLine(const std::string& line, Memory& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut)
|
void Config::tryParseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut)
|
||||||
{
|
{
|
||||||
std::istringstream tok(line);
|
std::istringstream tok(line);
|
||||||
|
|
||||||
@ -180,7 +209,62 @@ void Config::tryParseLine(const std::string& line, Memory& ram, Memory& rom, Slo
|
|||||||
|
|
||||||
insertCard(sCardType,slot,slts,gui);
|
insertCard(sCardType,slot,slts,gui);
|
||||||
}
|
}
|
||||||
else if (cmd == "import")
|
else if (cmd == "motherboard") {
|
||||||
|
std::string op;
|
||||||
|
tok >> op;
|
||||||
|
if (op == "ram") {
|
||||||
|
/* ram ROW BIT0 [BIT1 [... [BIT7]]]
|
||||||
|
* ram e -
|
||||||
|
* ram d 4096 MK4096 4K
|
||||||
|
* ram c 16K 4116 MK4116 MM5290 16K 16K 16K 16K
|
||||||
|
*/
|
||||||
|
std::string row;
|
||||||
|
tok >> row;
|
||||||
|
std::transform(row.begin(), row.end(), row.begin(), ::toupper);
|
||||||
|
if (row != "C" && row != "D" && row != "E") {
|
||||||
|
throw ConfigException("expected row to be C, D, or E");
|
||||||
|
}
|
||||||
|
std::string chip_model;
|
||||||
|
tok >> chip_model;
|
||||||
|
std::uint16_t siz = chip_size(chip_model);
|
||||||
|
for (std::uint_fast8_t bit = 0u; bit < 8u; ++bit) {
|
||||||
|
if (siz) {
|
||||||
|
ram.insert_chip(row, MemoryChip(siz,chip_model), bit);
|
||||||
|
} else {
|
||||||
|
ram.remove_chip(row, bit);
|
||||||
|
}
|
||||||
|
std::string chip_model_optional;
|
||||||
|
tok >> chip_model_optional;
|
||||||
|
if (chip_model_optional.length()) {
|
||||||
|
chip_model = chip_model_optional;
|
||||||
|
}
|
||||||
|
siz = chip_size(chip_model);
|
||||||
|
}
|
||||||
|
} else if (op == "strap") {
|
||||||
|
/* strap ROM K start-addr
|
||||||
|
* strap c 4K 0000
|
||||||
|
* strap d 4K 1000
|
||||||
|
* strap e 4K 2000
|
||||||
|
*/
|
||||||
|
std::string row;
|
||||||
|
tok >> row;
|
||||||
|
std::transform(row.begin(), row.end(), row.begin(), ::toupper);
|
||||||
|
if (row != "C" && row != "D" && row != "E") {
|
||||||
|
throw ConfigException("expected row to be C, D, or E");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string block_size;
|
||||||
|
tok >> block_size;
|
||||||
|
std::uint16_t siz = memory_block_size(block_size);
|
||||||
|
unsigned short base(0);
|
||||||
|
tok >> std::hex >> base;
|
||||||
|
// TODO validate siz/base combination
|
||||||
|
ram.strap_to(row, base, siz);
|
||||||
|
} else {
|
||||||
|
throw ConfigException("error at \"motherboard\"; expected \"ram\" or \"strap\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cmd == "import")
|
||||||
{
|
{
|
||||||
std::string sm;
|
std::string sm;
|
||||||
tok >> sm;
|
tok >> sm;
|
||||||
@ -216,10 +300,6 @@ void Config::tryParseLine(const std::string& line, Memory& ram, Memory& rom, Slo
|
|||||||
{
|
{
|
||||||
rom.load(base,memfile);
|
rom.load(base,memfile);
|
||||||
}
|
}
|
||||||
else if (romtype == "ram")
|
|
||||||
{
|
|
||||||
ram.load(base,memfile);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw ConfigException("error at \""+romtype+"\"; expected rom or ram");
|
throw ConfigException("error at \""+romtype+"\"; expected rom or ram");
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
class Memory;
|
class Memory;
|
||||||
|
class MemoryRandomAccess;
|
||||||
class Slots;
|
class Slots;
|
||||||
class ScreenImage;
|
class ScreenImage;
|
||||||
class CassetteIn;
|
class CassetteIn;
|
||||||
@ -42,14 +43,14 @@ private:
|
|||||||
static void unloadDisk(Slots& slts, int slot, int drive);
|
static void unloadDisk(Slots& slts, int slot, int drive);
|
||||||
static void saveDisk(Slots& slts, int slot, int drive);
|
static void saveDisk(Slots& slts, int slot, int drive);
|
||||||
static void insertCard(const std::string& cardType, int slot, Slots& slts, ScreenImage& gui);
|
static void insertCard(const std::string& cardType, int slot, Slots& slts, ScreenImage& gui);
|
||||||
static void tryParseLine(const std::string& line, Memory& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut);
|
static void tryParseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Config(const std::string& file_path);
|
Config(const std::string& file_path);
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
void parse(Memory& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut);
|
void parse(MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut);
|
||||||
static void parseLine(const std::string& line, Memory& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut);
|
static void parseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
epple2
|
epple2
|
||||||
Copyright (C) 2008 by Christopher A. Mosher <cmosher01@gmail.com>
|
|
||||||
|
Copyright © 2008, 2019, Christopher Alan Mosher, Shelton, CT, USA. <cmosher01@gmail.com>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -19,32 +20,76 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
#include <cstdlib>
|
||||||
#include "raminitializer.h"
|
#include "raminitializer.h"
|
||||||
|
|
||||||
const int Memory::CLEAR_VALUE(0);
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If any RAM IC sockets are empty, set the corresponding bits to 1 most of the time.
|
||||||
|
* But set to 0 instead, with probability 1 in 137 (a rough estimate obtained empirically)
|
||||||
|
*/
|
||||||
|
static std::uint8_t randomize_missing_bits(std::uint8_t v, const std::uint8_t bits) {
|
||||||
|
std::uint8_t bit = 1u;
|
||||||
|
for (std::uint_fast8_t i = 0; i < 8; ++i) {
|
||||||
|
if (bits & bit) {
|
||||||
|
double r = static_cast<double>(std::rand())/RAND_MAX;
|
||||||
|
if (r < 1.0/137.0) {
|
||||||
|
v &= ~bit;
|
||||||
|
} else {
|
||||||
|
v |= bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bit <<= 1;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Memory::Memory(const size_t n):
|
Memory::Memory(const size_t n):
|
||||||
bytes(n)
|
bytes(n),
|
||||||
{
|
clear_value(0u),
|
||||||
|
missing_bits(0u) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::clear()
|
|
||||||
{
|
|
||||||
std::fill(this->bytes.begin(),this->bytes.end(),CLEAR_VALUE);
|
void Memory::clear() {
|
||||||
|
std::fill(this->bytes.begin(), this->bytes.end(), this->clear_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::powerOn()
|
void Memory::init() {
|
||||||
{
|
RAMInitializer initRam(*this);
|
||||||
RAMInitializer initRam(*this);
|
initRam.init();
|
||||||
initRam.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::powerOff()
|
void Memory::load(const std::uint16_t base, std::istream& in) {
|
||||||
{
|
in.read(reinterpret_cast<char*>(&this->bytes[base]), static_cast<ptrdiff_t>(this->bytes.size()-base));
|
||||||
clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::load(const unsigned short base, std::istream& in)
|
|
||||||
{
|
|
||||||
in.read((char*)&this->bytes[base],this->bytes.size()-base);
|
void Memory::powerOn() {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Memory::powerOff() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Memory::size() const {
|
||||||
|
return this->bytes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t Memory::read(const std::uint16_t address) const {
|
||||||
|
std::uint8_t v = this->bytes[address];
|
||||||
|
if (this->missing_bits) {
|
||||||
|
v = randomize_missing_bits(v, this->missing_bits);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Memory::write(const std::uint16_t address, const std::uint8_t data) {
|
||||||
|
this->bytes[address] = data;
|
||||||
}
|
}
|
||||||
|
45
src/memory.h
45
src/memory.h
@ -20,34 +20,27 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
class Memory
|
class Memory {
|
||||||
{
|
private:
|
||||||
private:
|
std::vector<std::uint8_t> bytes;
|
||||||
std::vector<unsigned char> bytes;
|
const std::uint8_t clear_value;
|
||||||
static const int CLEAR_VALUE;
|
const std::uint8_t missing_bits;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Memory(const size_t n);
|
Memory(const size_t n);
|
||||||
size_t size() const
|
virtual ~Memory() { }
|
||||||
{
|
|
||||||
return this->bytes.size();
|
size_t size() const;
|
||||||
}
|
std::uint8_t read(const std::uint16_t address) const;
|
||||||
|
void write(const std::uint16_t address, const std::uint8_t data);
|
||||||
unsigned char read(const unsigned short address) const
|
void powerOn();
|
||||||
{
|
void powerOff();
|
||||||
return this->bytes[address];
|
|
||||||
}
|
void clear();
|
||||||
|
void init();
|
||||||
void write(const unsigned short address, const unsigned char data)
|
void load(const std::uint16_t base, std::istream& in);
|
||||||
{
|
|
||||||
this->bytes[address] = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
void powerOn();
|
|
||||||
void powerOff();
|
|
||||||
void load(const unsigned short base, std::istream& in);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
74
src/memorychip.cpp
Normal file
74
src/memorychip.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include "memorychip.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define K 1024
|
||||||
|
|
||||||
|
MemoryChip::MemoryChip(const std::uint16_t size, const std::string &id_model):
|
||||||
|
size_bits(size),
|
||||||
|
id_model(id_model) {
|
||||||
|
if (size_bits != 4*K && size_bits != 16*K) {
|
||||||
|
throw std::out_of_range("MemoryChip must be 4K or 16K");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryChip::MemoryChip(const MemoryChip &that):
|
||||||
|
size_bits(that.size_bits),
|
||||||
|
id_model(that.id_model) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryChip &MemoryChip::operator=(const MemoryChip &that) {
|
||||||
|
this->size_bits = that.size_bits;
|
||||||
|
this->id_model = that.id_model;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryChip::~MemoryChip() {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint16_t MemoryChip::size() const {
|
||||||
|
return this->size_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MemoryChip::id() const {
|
||||||
|
return this->id_model;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemoryChip::exists() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bitflag(const bool on, const std::uint8_t mask, std::uint8_t &byte) {
|
||||||
|
if (on) {
|
||||||
|
byte |= mask;
|
||||||
|
} else {
|
||||||
|
byte &= ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#define CYCLE 128u
|
||||||
|
#define CYCLE 2u
|
||||||
|
|
||||||
|
void MemoryChip::init(const std::uint8_t mask, std::vector<std::uint8_t> &bytes, const std::uint16_t size) const {
|
||||||
|
bool on = false;
|
||||||
|
std::uint8_t c = 0u;
|
||||||
|
for (std::uint16_t i = 0u; i < std::min(size, this->size_bits); ++i) {
|
||||||
|
bitflag(on, mask, bytes[i]);
|
||||||
|
if (CYCLE <= ++c) {
|
||||||
|
c = 0u;
|
||||||
|
on = !on;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryChipEmptySocket::MemoryChipEmptySocket():
|
||||||
|
MemoryChip(4*K,"[empty]") {
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryChipEmptySocket::~MemoryChipEmptySocket() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemoryChipEmptySocket::exists() const {
|
||||||
|
return false;
|
||||||
|
}
|
29
src/memorychip.h
Normal file
29
src/memorychip.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef MEMORYCHIP_H
|
||||||
|
#define MEMORYCHIP_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class MemoryChip {
|
||||||
|
private:
|
||||||
|
std::uint16_t size_bits;
|
||||||
|
std::string id_model;
|
||||||
|
public:
|
||||||
|
MemoryChip(const std::uint16_t size, const std::string &id_model);
|
||||||
|
MemoryChip(const MemoryChip &that);
|
||||||
|
MemoryChip &operator=(const MemoryChip &that);
|
||||||
|
virtual ~MemoryChip();
|
||||||
|
std::uint16_t size() const;
|
||||||
|
std::string id() const;
|
||||||
|
virtual void init(const std::uint8_t mask, std::vector<std::uint8_t> &bytes, const std::uint16_t size) const;
|
||||||
|
virtual bool exists() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MemoryChipEmptySocket : public MemoryChip {
|
||||||
|
public:
|
||||||
|
MemoryChipEmptySocket();
|
||||||
|
virtual ~MemoryChipEmptySocket();
|
||||||
|
virtual bool exists() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MEMORYCHIP_H
|
149
src/memoryrandomaccess.cpp
Normal file
149
src/memoryrandomaccess.cpp
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#include "memoryrandomaccess.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
#define K 1024u
|
||||||
|
|
||||||
|
MemoryRandomAccess::MemoryRandomAccess(int &revision):
|
||||||
|
revision(revision),
|
||||||
|
rowE('E'),
|
||||||
|
strapE(rowE),
|
||||||
|
rowD('D'),
|
||||||
|
strapD(rowD),
|
||||||
|
rowC('C'),
|
||||||
|
strapC(rowC) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryRow &MemoryRandomAccess::row_of(const std::string &row) {
|
||||||
|
if (row == "E") {
|
||||||
|
return this->rowE;
|
||||||
|
}
|
||||||
|
if (row == "D") {
|
||||||
|
return this->rowD;
|
||||||
|
}
|
||||||
|
if (row == "C") {
|
||||||
|
return this->rowC;
|
||||||
|
}
|
||||||
|
throw std::logic_error("expected C/D/E");
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryStrapping &MemoryRandomAccess::strapping_of(const std::string &row) {
|
||||||
|
if (row == "E") {
|
||||||
|
return this->strapE;
|
||||||
|
}
|
||||||
|
if (row == "D") {
|
||||||
|
return this->strapD;
|
||||||
|
}
|
||||||
|
if (row == "C") {
|
||||||
|
return this->strapC;
|
||||||
|
}
|
||||||
|
throw std::logic_error("expected C/D/E");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRandomAccess::insert_chip(const std::string &row, MemoryChip chip, const std::uint_fast8_t socket) {
|
||||||
|
row_of(row).insert_chip(chip, socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRandomAccess::remove_chip(const std::string &row, const std::uint_fast8_t socket) {
|
||||||
|
row_of(row).remove_chip(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRandomAccess::strap_to(const std::string &row, std::uint16_t addr_base, std::uint16_t addr_size) {
|
||||||
|
strapping_of(row).strap_to(addr_base, addr_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemoryRandomAccess::k20or24() const {
|
||||||
|
const std::uint32_t k = this->rowC.size() + this->rowD.size() + this->rowD.size();
|
||||||
|
return (k==20*K) || (k==24*K);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for 20K or 24K on rev. 0: pages 40-5F are dup w/ 60-7F */
|
||||||
|
std::uint8_t MemoryRandomAccess::buggyRamRead(const std::uint16_t address) const {
|
||||||
|
std::uint16_t ax = address & ~0x2000u;
|
||||||
|
if (this->strapE.contains(ax)) {
|
||||||
|
return this->strapE.read(ax);
|
||||||
|
}
|
||||||
|
if (this->strapD.contains(ax)) {
|
||||||
|
return this->strapD.read(ax);
|
||||||
|
}
|
||||||
|
if (this->strapC.contains(ax)) {
|
||||||
|
return this->strapC.read(ax);
|
||||||
|
}
|
||||||
|
ax = address | 0x2000u;
|
||||||
|
if (this->strapE.contains(ax)) {
|
||||||
|
return this->strapE.read(ax);
|
||||||
|
}
|
||||||
|
if (this->strapD.contains(ax)) {
|
||||||
|
return this->strapD.read(ax);
|
||||||
|
}
|
||||||
|
if (this->strapC.contains(ax)) {
|
||||||
|
return this->strapC.read(ax);
|
||||||
|
}
|
||||||
|
return MemoryRow::missing_memory_byte_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t MemoryRandomAccess::read(const std::uint16_t address) const {
|
||||||
|
if (this->revision == 0 && k20or24() && ((address & 0xC000u) == 0x4000u)) {
|
||||||
|
return buggyRamRead(address);
|
||||||
|
}
|
||||||
|
if (this->strapE.contains(address)) {
|
||||||
|
return this->strapE.read(address);
|
||||||
|
}
|
||||||
|
if (this->strapD.contains(address)) {
|
||||||
|
return this->strapD.read(address);
|
||||||
|
}
|
||||||
|
if (this->strapC.contains(address)) {
|
||||||
|
return this->strapC.read(address);
|
||||||
|
}
|
||||||
|
return MemoryRow::missing_memory_byte_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRandomAccess::buggyRamWrite(std::uint16_t address, const std::uint8_t data) {
|
||||||
|
std::uint16_t ax = address & ~0x2000u;
|
||||||
|
if (this->strapE.contains(ax)) {
|
||||||
|
this->strapE.write(ax, data);
|
||||||
|
}
|
||||||
|
if (this->strapD.contains(ax)) {
|
||||||
|
this->strapD.write(ax, data);
|
||||||
|
}
|
||||||
|
if (this->strapC.contains(ax)) {
|
||||||
|
this->strapC.write(ax, data);
|
||||||
|
}
|
||||||
|
ax = address | 0x2000u;
|
||||||
|
if (this->strapE.contains(ax)) {
|
||||||
|
this->strapE.write(ax, data);
|
||||||
|
}
|
||||||
|
if (this->strapD.contains(ax)) {
|
||||||
|
this->strapD.write(ax, data);
|
||||||
|
}
|
||||||
|
if (this->strapC.contains(ax)) {
|
||||||
|
this->strapC.write(ax, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRandomAccess::write(const std::uint16_t address, const std::uint8_t data) {
|
||||||
|
if (this->revision == 0 && k20or24() && ((address & 0xC000u) == 0x4000u)) {
|
||||||
|
buggyRamWrite(address, data);
|
||||||
|
}
|
||||||
|
if (this->strapE.contains(address)) {
|
||||||
|
this->strapE.write(address, data);
|
||||||
|
}
|
||||||
|
if (this->strapD.contains(address)) {
|
||||||
|
this->strapD.write(address, data);
|
||||||
|
}
|
||||||
|
if (this->strapC.contains(address)) {
|
||||||
|
this->strapC.write(address, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRandomAccess::powerOn() {
|
||||||
|
this->rowE.powerOn();
|
||||||
|
this->rowD.powerOn();
|
||||||
|
this->rowC.powerOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRandomAccess::powerOff() {
|
||||||
|
this->rowE.powerOff();
|
||||||
|
this->rowD.powerOff();
|
||||||
|
this->rowC.powerOff();
|
||||||
|
}
|
38
src/memoryrandomaccess.h
Normal file
38
src/memoryrandomaccess.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef MEMORYRANDOMACCESS_H
|
||||||
|
#define MEMORYRANDOMACCESS_H
|
||||||
|
|
||||||
|
#include "memorystrapping.h"
|
||||||
|
#include "memoryrow.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class MemoryRandomAccess {
|
||||||
|
private:
|
||||||
|
int &revision;
|
||||||
|
MemoryRow rowE;
|
||||||
|
MemoryStrapping strapE;
|
||||||
|
MemoryRow rowD;
|
||||||
|
MemoryStrapping strapD;
|
||||||
|
MemoryRow rowC;
|
||||||
|
MemoryStrapping strapC;
|
||||||
|
|
||||||
|
MemoryRow &row_of(const std::string &row);
|
||||||
|
MemoryStrapping &strapping_of(const std::string &row);
|
||||||
|
std::uint8_t buggyRamRead(std::uint16_t address) const;
|
||||||
|
void buggyRamWrite(std::uint16_t address, const std::uint8_t data);
|
||||||
|
bool k20or24() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MemoryRandomAccess(int &revision);
|
||||||
|
|
||||||
|
void insert_chip(const std::string &row, MemoryChip chip, const std::uint_fast8_t socket);
|
||||||
|
void remove_chip(const std::string &row, const std::uint_fast8_t socket);
|
||||||
|
void strap_to(const std::string &row, std::uint16_t addr_base, std::uint16_t addr_size);
|
||||||
|
|
||||||
|
std::uint8_t read(std::uint16_t address) const;
|
||||||
|
void write(std::uint16_t address, const std::uint8_t data);
|
||||||
|
void powerOn();
|
||||||
|
void powerOff();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
131
src/memoryrow.cpp
Normal file
131
src/memoryrow.cpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#include "memoryrow.h"
|
||||||
|
#include <exception>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If any RAM IC sockets are empty, set the corresponding bits to 1 most of the time.
|
||||||
|
* For some addresses it seems they are always 1, but for other addresses they can return
|
||||||
|
* 0 sometimes, empirically I've seen anywhere from 8% to 15% of the time.
|
||||||
|
*/
|
||||||
|
static std::uint8_t randomize_missing_bits(std::uint8_t v, const std::uint8_t bits) {
|
||||||
|
std::uint8_t bit = 1u;
|
||||||
|
for (std::uint_fast8_t i = 0; i < 8; ++i) {
|
||||||
|
if (bits & bit) {
|
||||||
|
double r = static_cast<double>(std::rand())/RAND_MAX;
|
||||||
|
if (r < 0.11) {
|
||||||
|
v &= ~bit;
|
||||||
|
} else {
|
||||||
|
v |= bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bit <<= 1;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MemoryRow::MemoryRow(const char label):
|
||||||
|
label(label) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryRow::~MemoryRow() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRow::insert_chip(MemoryChip chip, const std::uint_fast8_t socket) {
|
||||||
|
if (socket < 8u) {
|
||||||
|
remove_chip(socket);
|
||||||
|
if (chip.exists()) {
|
||||||
|
this->chips[socket] = chip;
|
||||||
|
this->missing_bits &= ~(1u << socket);
|
||||||
|
this->values_stored.resize(calculate_size());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw std::out_of_range("socket must be < 8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRow::remove_chip(const std::uint_fast8_t socket) {
|
||||||
|
if (socket < 8u) {
|
||||||
|
this->chips[socket] = MemoryChipEmptySocket();
|
||||||
|
this->missing_bits |= (1u << socket);
|
||||||
|
this->values_stored.resize(calculate_size());
|
||||||
|
} else {
|
||||||
|
throw std::out_of_range("socket must be < 8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If no chips, return 0.
|
||||||
|
* Otherwise, return minimum of existing chips (4K or 16K)
|
||||||
|
*/
|
||||||
|
std::uint16_t MemoryRow::calculate_size() const {
|
||||||
|
std::uint16_t size_new = 0u;
|
||||||
|
|
||||||
|
for (std::uint_fast8_t i_chip = 0; i_chip < 8; ++i_chip) {
|
||||||
|
const MemoryChip &chip = this->chips[i_chip];
|
||||||
|
if (chip.exists()) {
|
||||||
|
const std::uint16_t s = chip.size();
|
||||||
|
if (size_new == 0u || s < size_new) {
|
||||||
|
size_new = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return size_new;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRow::powerOff() {
|
||||||
|
this->power = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calls init of each chip, and uses a bit mask to assemble into bytes.
|
||||||
|
*/
|
||||||
|
void MemoryRow::powerOn() {
|
||||||
|
if (!this->power) {
|
||||||
|
this->power = true;
|
||||||
|
|
||||||
|
std::uint8_t mask_bit = 1u;
|
||||||
|
for (std::uint_fast8_t i_bit = 0; i_bit < 8; ++i_bit) {
|
||||||
|
const MemoryChip &chip = this->chips[i_bit];
|
||||||
|
if (chip.exists()) {
|
||||||
|
chip.init(mask_bit, this->values_stored, size());
|
||||||
|
}
|
||||||
|
mask_bit <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint16_t MemoryRow::size() const {
|
||||||
|
return static_cast<std::uint16_t>(this->values_stored.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t MemoryRow::missing_memory_byte_value() {
|
||||||
|
return randomize_missing_bits(0xFFu, 0xFFu);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t MemoryRow::read(const std::uint16_t address_offset) const {
|
||||||
|
if (this->power) {
|
||||||
|
std::uint8_t v;
|
||||||
|
if (address_offset < this->values_stored.size()) {
|
||||||
|
v = this->values_stored[address_offset];
|
||||||
|
if (this->missing_bits) {
|
||||||
|
v = randomize_missing_bits(v, this->missing_bits);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v = missing_memory_byte_value();
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
} else {
|
||||||
|
throw std::logic_error("cannot read memory when power is off");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryRow::write(const std::uint16_t address, const std::uint8_t data) {
|
||||||
|
if (this->power) {
|
||||||
|
this->values_stored[address] = data;
|
||||||
|
} else {
|
||||||
|
throw std::logic_error("cannot write memory when power is off");
|
||||||
|
}
|
||||||
|
}
|
49
src/memoryrow.h
Normal file
49
src/memoryrow.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef MEMORYROW_H
|
||||||
|
#define MEMORYROW_H
|
||||||
|
|
||||||
|
#include "memorychip.h"
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class MemoryRow {
|
||||||
|
private:
|
||||||
|
/* C, D, E */
|
||||||
|
const char label;
|
||||||
|
|
||||||
|
bool power = false;
|
||||||
|
|
||||||
|
/* 8 sockets for memory chips (empty socket represented by MemoryChipEmptySocket) */
|
||||||
|
std::array<MemoryChip,8> chips = {MemoryChipEmptySocket(),MemoryChipEmptySocket(),MemoryChipEmptySocket(),MemoryChipEmptySocket(),MemoryChipEmptySocket(),MemoryChipEmptySocket(),MemoryChipEmptySocket(),MemoryChipEmptySocket()};
|
||||||
|
|
||||||
|
/* bit mask of empty chip sockets */
|
||||||
|
std::uint8_t missing_bits = 0xFFu;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Instead of storing each bit in a MemoryChip (too slow), we store the data here as bytes,
|
||||||
|
* representing one bit for each chip.
|
||||||
|
*/
|
||||||
|
std::vector<std::uint8_t> values_stored;
|
||||||
|
|
||||||
|
std::uint16_t calculate_size() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MemoryRow(const char label);
|
||||||
|
virtual ~MemoryRow();
|
||||||
|
|
||||||
|
void insert_chip(MemoryChip chip, const std::uint_fast8_t socket);
|
||||||
|
void remove_chip(const std::uint_fast8_t socket);
|
||||||
|
void powerOff();
|
||||||
|
void powerOn();
|
||||||
|
|
||||||
|
/* 4K or 16K, size of each chip (or minimum in corner case of mixed sizes) */
|
||||||
|
std::uint16_t size() const;
|
||||||
|
|
||||||
|
std::uint8_t read(const std::uint16_t address) const;
|
||||||
|
void write(const std::uint16_t address, const std::uint8_t data);
|
||||||
|
|
||||||
|
static std::uint8_t missing_memory_byte_value();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MEMORYROW_H
|
23
src/memorystrapping.cpp
Normal file
23
src/memorystrapping.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "memorystrapping.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
MemoryStrapping::MemoryStrapping(MemoryRow &row):
|
||||||
|
row(row) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryStrapping::strap_to(std::uint16_t addr_base, std::uint16_t addr_size) {
|
||||||
|
this->addr_base = addr_base;
|
||||||
|
this->addr_size = addr_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemoryStrapping::contains(std::uint16_t address) const {
|
||||||
|
return this->addr_base <= address && address < this->addr_base + std::min(this->row.size(), this->addr_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t MemoryStrapping::read(const std::uint16_t address) const {
|
||||||
|
return this->row.read(address - this->addr_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryStrapping::write(const std::uint16_t address, const std::uint8_t data) {
|
||||||
|
this->row.write(address - this->addr_base, data);
|
||||||
|
}
|
20
src/memorystrapping.h
Normal file
20
src/memorystrapping.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef MEMORYSTRAPPING_H
|
||||||
|
#define MEMORYSTRAPPING_H
|
||||||
|
|
||||||
|
#include "memoryrow.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class MemoryStrapping {
|
||||||
|
private:
|
||||||
|
MemoryRow &row;
|
||||||
|
std::uint16_t addr_base;
|
||||||
|
std::uint16_t addr_size;
|
||||||
|
public:
|
||||||
|
MemoryStrapping(MemoryRow &row);
|
||||||
|
void strap_to(std::uint16_t addr_base, std::uint16_t addr_size);
|
||||||
|
bool contains(std::uint16_t address) const;
|
||||||
|
std::uint8_t read(const std::uint16_t address) const;
|
||||||
|
void write(const std::uint16_t address, const std::uint8_t data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -40,7 +40,7 @@ void RAMInitializer::init()
|
|||||||
putBytesUntilFull(b++,2);
|
putBytesUntilFull(b++,2);
|
||||||
putBytesUntilFull(b++,2);
|
putBytesUntilFull(b++,2);
|
||||||
putBytesUntilFull(b++,1);
|
putBytesUntilFull(b++,1);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
void RAMInitializer::putBytesUntilFull(int bit, int pat)
|
void RAMInitializer::putBytesUntilFull(int bit, int pat)
|
||||||
|
Loading…
Reference in New Issue
Block a user