1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-30 22:29:56 +00:00

Added logic to try to spot when the first program is BASIC and, if so, what the correct memory model is, then to get that information to the Vic. Though it currently then gets overwritten by the view controller. Grrrr.

This commit is contained in:
Thomas Harte 2016-09-07 22:17:19 -04:00
parent 556b77f2fd
commit 50175a9aed
6 changed files with 116 additions and 11 deletions

View File

@ -269,10 +269,39 @@ void Machine::set_prg(const char *file_name, size_t length, const uint8_t *data)
#pragma mar - Tape
void Machine::configure_as_target(const StaticAnalyser::Target &target)
{
if(target.tapes.size())
{
_tape.set_tape(target.tapes.front());
}
if(_should_automatically_load_media)
{
if(target.loadingCommand.length()) // TODO: and automatic loading option enabled
{
set_typer_for_string(target.loadingCommand.c_str());
}
switch(target.vic20.memory_model)
{
case StaticAnalyser::Vic20MemoryModel::Unexpanded:
set_memory_size(Default);
break;
case StaticAnalyser::Vic20MemoryModel::EightKB:
set_memory_size(ThreeKB);
break;
case StaticAnalyser::Vic20MemoryModel::ThirtyTwoKB:
set_memory_size(ThirtyTwoKB);
break;
}
}
}
void Machine::set_tape(std::shared_ptr<Storage::Tape::Tape> tape)
{
_tape.set_tape(tape);
if(_should_automatically_load_media) set_typer_for_string("LOAD\nRUN\n");
// _tape.set_tape(tape);
// if(_should_automatically_load_media) set_typer_for_string("LOAD\nRUN\n");
}
void Machine::tape_did_change_input(Tape *tape)

View File

@ -21,6 +21,7 @@
#include "../../../Storage/Tape/Tape.hpp"
#include "../../../Storage/Disk/Disk.hpp"
#include "../../../StaticAnalyser/StaticAnalyser.hpp"
namespace Commodore {
namespace Vic20 {
@ -260,6 +261,7 @@ class Machine:
~Machine();
void set_rom(ROMSlot slot, size_t length, const uint8_t *data);
void configure_as_target(const StaticAnalyser::Target &target);
void set_prg(const char *file_name, size_t length, const uint8_t *data);
void set_tape(std::shared_ptr<Storage::Tape::Tape> tape);
void set_disk(std::shared_ptr<Storage::Disk::Disk> disk);

View File

@ -41,6 +41,10 @@ class Vic20Document: MachineDocument {
return "Vic20Document"
}
override func configureAs(analysis: CSStaticAnalyser) {
analysis.applyToMachine(vic20)
}
override func readFromURL(url: NSURL, ofType typeName: String) throws {
if let pathExtension = url.pathExtension {
switch pathExtension.lowercaseString {

View File

@ -46,6 +46,12 @@ using namespace Commodore::Vic20;
[self setROM:rom slot:Drive];
}
- (void)applyTarget:(StaticAnalyser::Target)target {
@synchronized(self) {
_vic20.configure_as_target(target);
}
}
- (BOOL)openTAPAtURL:(NSURL *)URL {
@synchronized(self) {
try {

View File

@ -36,12 +36,74 @@ void StaticAnalyser::Commodore::AddTargets(
// continue if there are any files
if(files.size())
{
// TODO: decide between ,1 (don't relocate; for machine code) and ,0 (relocate; for BASIC)
// TODO: decide memory model (based on extents and sizes)
// TODO: decide machine (disassemble?)
bool is_basic = true;
// decide whether this is a BASIC file based on the proposition that:
// (1) they're always relocatable; and
// (2) they have a per-line structure of:
// [4 bytes: address of start of next line]
// [4 bytes: this line number]
// ... null-terminated code ...
// (with a next line address of 0000 indicating end of program)ß
if(files.front().type != File::RelocatableProgram) is_basic = false;
else
{
uint16_t line_address = 0;
int line_number = -1;
uint16_t starting_address = files.front().starting_address;
line_address = starting_address;
is_basic = false;
while(1)
{
if(line_address - starting_address >= files.front().data.size() + 2) break;
uint16_t next_line_address = files.front().data[line_address - starting_address];
next_line_address |= files.front().data[line_address - starting_address + 1] << 8;
if(!next_line_address)
{
is_basic = true;
break;
}
if(next_line_address < line_address + 5) break;
if(line_address - starting_address >= files.front().data.size() + 5) break;
uint16_t next_line_number = files.front().data[line_address - starting_address + 2];
next_line_number |= files.front().data[line_address - starting_address + 3] << 8;
if(next_line_number <= line_number) break;
line_number = (uint16_t)next_line_number;
line_address = next_line_address;
}
}
target.vic20.memory_model = Vic20MemoryModel::Unexpanded;
if(is_basic)
{
target.loadingCommand = "LOAD\"\",1,0\nRUN\n";
switch(files.front().starting_address)
{
case 0x1001:
default: break;
case 0x1201:
target.vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
break;
case 0x0401:
target.vic20.memory_model = Vic20MemoryModel::EightKB;
break;
}
}
else
{
// TODO: this is machine code. So, ummm?
}
target.tapes = tapes;
}
}
if(target.tapes.size() || target.cartridges.size() || target.disks.size())
destination.push_back(target);
}
}

View File

@ -19,6 +19,12 @@
namespace StaticAnalyser {
enum class Vic20MemoryModel {
Unexpanded,
EightKB,
ThirtyTwoKB
};
/*!
A list of disks, tapes and cartridges plus information about the machine to which to attach them and its configuration,
and instructions on how to launch the software attached, plus a measure of confidence in this target's correctness.
@ -33,11 +39,7 @@ struct Target {
union {
struct {
enum class Vic20 {
Unexpanded,
EightKB,
ThirtyTwoKB
} memoryModel;
Vic20MemoryModel memory_model;
bool has_c1540;
} vic20;