6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Apr 26, 2024 3:27 am

All times are UTC




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Apr 25, 2021 10:58 am 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
For quite a while, I've been thinking of a technique to reliably identify a 6502 host system. There are two purposes for such identification. The first purpose is to allow an accelerator in a 6502 socket (such as MCL65+) to auto-configure in known hosts. Alternatively, an accelerator may present a pre-boot menu before the host firmware is run. This requires rendering a text menu or similar using an appropriate set of text symbols or bitmap display.

The other purpose is to make portable binaries which will load and run on Planck, Ruby, Commander X16, Foenix C256, Commodore, Acorn and other hardware.

After much consideration, I believe that the six bytes of the RESET, NMI and IRQ vectors may be sufficiently unique. Some versions of Commodore hardware have, for example, a flag for NTSC or PAL. Likewise, a Commodore 128 in Commodore 64 mode will be mistaken for a Commodore 64. This is arguably correct operation.

Regardless, a table of vectors should be sufficient for a portable binary to determine if it has access to a VIC, VIC II, 6845, SAA5050, TMS9918 or similar at a given address. It should also be sufficient to determine kernel calling conventions and available functionality.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 25, 2021 11:19 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
Auto-configuring an in-socket accelerator is something we'd like to do for beeb816 too.


Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 25, 2021 12:56 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1398
Location: Scotland
Ruby is all RAM and its top 3 vectors potentially change at every software build. I've not even thought about making them 'constant', although reset often points to $C000.

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 29, 2021 9:58 am 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
drogon on Sun 25 Apr 2021 wrote:
Ruby is all RAM and its top 3 vectors potentially change at every software build.


Dang it! That's an annoying exception. Do you have relatively stable Acorn or Commodore vectors elsewhere in page 0xFF?

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 29, 2021 1:18 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1398
Location: Scotland
Sheep64 wrote:
drogon on Sun 25 Apr 2021 wrote:
Ruby is all RAM and its top 3 vectors potentially change at every software build.


Dang it! That's an annoying exception. Do you have relatively stable Acorn or Commodore vectors elsewhere in page 0xFF?


Not just Ruby - have you looked at the ROM versions on the Apple II series?

A potential issue is the question of just how you make a binary so cross platform compatible without incurring huge overhead and inside that binary it's own set of compatibility routines - to e.g. "print a character in A" - just in-case some systems do it differently. (e.g. which registers get trashed, etc.)

And in systems such as the BBC Micro & Ruby binaries are sort of expected to live in a particular location ($8000) and be < 16KB in size, or alternatively live somewhere like $2000 upwards, bearing in-mind the location of video RAM in the BBC Micro (and Apple II, etc.).

So thinking more about it, it's a great thing to be able to achieve, but the practicalities are going to be somewhat challenging.

If you know you were running on a Ruby or BBC Micro then there are system calls to tell you the operating system version, but under Ruby816 some of the standard OS entry vectors have changed from the Acorn MOS ones, although in Ruby'02 they are the same... Then there's the Ruby 134 (which many never exist, but in the '134 the hardware vectors are somewhat much more 'verbose' than even in the '816, so the software vectors need to move (again). Also, because of the '134, (possibly the '265 too) I'm in the process of almost abandoning the standard Acorn MOS vectors at $FF80 upwards and moving the whole lot down to $FDxx... ($FExx is hardware IO) For my Ruby code it's a simple re-assemble and reload. (I have a workaround for BBC Basic which is the only "classic" Acorn software I care for right now).

So how to positively identify a Ruby board... Actually, while the vectors are in RAM, the RESET code almost always points to $C000. Is that enough? If not, how about looking at $C003/4/5/6/7/8 where I could place some data and a checksum (just an xor of those bytes) so you could read the first byte at $C003 - gives the Ruby type - 02/816/134, 2nd byte might be clock speed (16 Mhz), 3rd byte RAM (in KB as a power of 2, so 64KB is 6, 512KB is 9) and maybe some more board ID data... However there might be a chance the checksum would 'work' when not on a Ruby board, so there is always going to be the risk of mis-identification. then what?

For my own code, I'm conditionally assembling for now.

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Sun May 09, 2021 12:14 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
I hoped that I could increase portability of software among contemporary systems. However, drogon notes that such systems are either in flux or are sufficiently general to have absolutely no identifying features. This largely restricts the technique to mass produced systems; many of which have ceased production. This would reduce portability to islands of contemporary systems and a common sea of legacy systems - unless we follow specific conventions.

I suggest a six byte sequence followed by one byte to specify ABI and one byte to specify memory map. The next problem is where to place such a sequence. My first suggestion is at the start of page $FF but some systems use this region for I/O. Approximately every other page is reserved in some form. This includes Steckschwein's I/O on page $02 and Rockwell microcontrollers placing I/O in the second half of page $00. I presume that every other location of zero page is similarly reserved. Therefore, I ask, is anyone using $01F8-$01FF immediately prior to loading an application? I don't care about legacy cases, such as Acorn ROMs using obscure locations because that is already covered by identifying a known set of vectors.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
PostPosted: Sun May 09, 2021 12:26 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1398
Location: Scotland
Sheep64 wrote:
I suggest a six byte sequence followed by one byte to specify ABI and one byte to specify memory map. The next problem is where to place such a sequence. My first suggestion is at the start of page $FF but some systems use this region for I/O. Approximately every other page is reserved in some form. This includes Steckschwein's I/O on page $02 and Rockwell microcontrollers placing I/O in the second half of page $00. I presume that every other location of zero page is similarly reserved. Therefore, I ask, is anyone using $01F8-$01FF immediately prior to loading an application? I don't care about legacy cases, such as Acorn ROMs using obscure locations because that is already covered by identifying a known set of vectors.


Just about every system that does:
Code:
    ldx    #$FF
    txs


at power-on time will use $01F8 through $01FF ...

So probably most of them, even though initialising the stack isn't technically needed to run code it keeps things tidy.

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Sun May 09, 2021 12:31 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
Actually, that's the wrong end of the stack page. Is anyone using $0100-$0107 or similar?

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
PostPosted: Mon May 10, 2021 2:44 am 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
drogon wrote:
even though initialising the stack isn't technically needed to run code it keeps things tidy.

It is needed for indexing into the stack with TSX, <mnemonic>1xx,X where the xx is how far into the stack you want to index. If you don't do the LDX #FF, TXS up front, you'll have to keep doing INX and DEX a lot to move around to index into different bytes in a stack frame, making it very inefficient. Otherwise, with a random start point, if the stack wraps from $100 to $1FF to $1FE long before the stack space is full, the abs,X indexing could put you into page 2, completely out of the stack area. For example, if you started randomly at $107 and put nine bytes on the stack, they would be at $107 through $100, then wrap to $1FF, and S would contain $FE. Now if you do TSX, LDA $105,X, $105+$FE puts you at $203, which is out of the stack area.

(This is from the 6502 stacks treatise.)

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Tue May 11, 2021 10:13 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
The 6800 and the 6809 are not compatible at the machine code level.

The FLEX operating system uses the .CMD file extension for both processors. This was an unfortunate choice as running a program on the "wrong" processor results in locking up the system or worse.

My solution is to include a short stub at the beginning of my programs to identify the processor and perform an orderly exit on the wrong one.

The code for the 6800:
Code:
        clra                    ; Clear carry flag
        fcb     $D              ; Test byte at $D on 6809
        fcb     $D              ; Set carry twice on 6800

        bcs     CPUOK

        fcb     $8E             ; ldx #BadCPU
        fdb     BadCPU
        jsr     $CD1E           ; PSTRNG
        jmp     $CD03           ; WARMS

BadCPU  fcc     'This program requires a 6800 processor'
        fcb     4

CPUOK

And for the 6809:
Code:
        clra                    ; Clear carry flag
        fcb     $D              ; Test byte at $D on 6809
        fcb     $D              ; Set carry twice on 6800

        bcc     CPUOK

        fcb     $CE             ; ldx $BadCPU
        fdb     BadCPU
        jsr     $AD1E           ; PSTRNG
        jmp     $AD03           ; WARMS

BadCPU  fcc     'This program requires a 6809 processor'
        fcb     4

CPUOK


The Xerox 16/8 can boot and run CP/M-80, CP/M-86 and MS-DOS. CP/M-80 and MS-DOS both use .COM for programs. I also came up with stubs for those, but I will have to search my archives for it. Other systems with the same problem include some models of Kaypro and Zenith computers and the CompuPro 8085/88 CPU board.

It will probably be best to identify 6502 vs 65C02 vs 65816 first, then try to identify the host hardware.


Top
 Profile  
Reply with quote  
PostPosted: Sun May 16, 2021 3:39 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
drogon on Thu 29 Apr 2021 wrote:
how you make a binary so cross platform compatible without incurring huge overhead


This divides into two cases.

In the case of an accelerator's pre-boot menu, there is absolutely no requirement to run anything inside a legacy host's address-space. It is possible, for example, to initialize Acorn 6845 using C++ and Arduino API. This has the advantage that it is possible to ignore any stray interrupts from the uninitialized system. However, there is zero opportunity to share library routines - either developed while writing the menu system or previously available to control peripherals, such as 6522. Furthermore, running the menu outside of 6502 simulation concentrates a rather bizarre corner case of dependencies including compiler dialect, I/O API and the specific pin-out of the accelerator - in addition the specifics of multiple 6502 memory maps.

In some regards, it may be more difficult to write a 6502 accelerator pre-boot menu in 6502 assembly - or the bytecode of your choice, including BCPL or BASIC. In other regards, it offers a two way flow of code re-use. In the case accelerator pre-boot menu, program size is not particularly constrained and may use memory which would ordinarily be reserved after boot. Unfortunately, in this case, strings have to be poked on a bitmap display or sent via serial. A bitmap font may be shared by all hosts if platform specific versions cannot be easily located. In the very worst case, where functionality diverges or exceeds available memory, a host may be identified and then a menu for each platform may be decompressed. Accelerators are likely to have 256KB ROM. Decompressed menu programs across all platforms may exceed 800KB.

In the case of application portability, I will be disappointed if host identification and processor feature tests add 1KB to a binary. Assuming exact matches for vectors, it is possible to fit a table of 32 entries for ABI and memory map into 256 bytes. Assuming range matches for vectors, 16 or so are possible in the same space. However, range matching vastly increases opportunity for false positives.

To make a system call, the minimum native set is GETCHR, PUTCHR, LOAD block and SAVE block. Indirection for each system call will determine wrapper function. These may include GETCHR on Acorn, GETCHR on Communicator, GETCHR on Ruby, GETCHR on Planck, GETCHR on PET, GETCHR on VIC20 and GETCHR on Apple II. Your binary may support no more than one platform and each wrapper is likely to be less than 20 bytes. You do not have to support all of Acorn's API on Commodore - unless you want to. You may also want API feature tests. "Does this platform have a printer output?" may indirect to an arbitrary test. In the trivial case, CLC // RTS indicates no. The application may then hide print options when running on a platform which does not support printing. Effectively, functionality is selectively culled on each platform. Only the useful subset of available functionality is presented. This leads to the curious case where all platforms may support facets of an application but no platform supports it in full.

Applications are not linked with screen scrolling, keyboard scanning, serial drivers, printer drivers or sound generation unless such functionality is essential and commonly absent from target platforms. Unfortunately, applications may be statically linked with POSIX cruft, such as printf.

drogon on Thu 29 Apr 2021 wrote:
I'm in the process of almost abandoning the standard Acorn MOS vectors at $FF80 upwards and moving the whole lot down to $FDxx... ($FExx is hardware IO)


Commodore, Acorn and W65C265 use the same memory locations for vectors. Applying lighthouse protocol, one of these is preferentially unmoved. Personally, I'd abandon page $FF and leave all of it for microcontroller hardware vectors - or anyone brave enough to use it for I/O. For example, jfoucher's Planck uses approximately half of page $FF for I/O. Other CPLD systems do similar. However, I would move an Acorn ABI to page $FB. It feels *wrong* telling an Acorn 6502 application to jump via page $FC, $FD or $FE (FRED, JIM or SHEILA). Likewise for a Commodore ABI in the same address-space, although less so. Therefore, to minimize unease, I suggest:-

  • Hardware indirection vectors working backward from the end of page $FF.
  • Re-located Commodore jump vectors working backward from the end of page $FD.
  • Re-located Acorn indirection vectors working backward from the end of page $FB.

I believe this would be compatible with W65C134, W65C265, Planck, Ruby, Steckschwein and other systems.

drogon on Thu 29 Apr 2021 wrote:
I have a workaround for BBC Basic which is the only "classic" Acorn software I care for right now


Do you transparently patch known binaries? I've suggested similar for Sargon II Chess. I believe that faster processors may look two or three moves further ahead without screwing the weighted score system.

In general, we have an interplay where application may identify operating system while operating system may identify application. The problem is that useful operating systems and applications pre-date this scheme. An operating system which is aware of legacy applications may patch binaries. Likewise, an application may adapt to a known set of legacy operating systems. The interesting part occurs when an aware application runs on an aware operating system. In this case, a superset of legacy ABIs may be invoked.

drogon on Thu 29 Apr 2021 wrote:
So how to positively identify a Ruby board...


We cannot use $C000 because that is the address of a 6522 on some systems. Actually, we cannot use page $00, page $02-03, page $80-$DF or page $FC-$FF. I may have missed cases but I believe that part of page $01 is available. Immediately prior to executing an application, place six bytes of your choice at $0100-$0105 followed by zero, zero. The six bytes should not look like a string, return address, vectors or fresh memory and will be used on all participating platforms. Something like $A4, $4F, $01, $FE would be a suitable start. Ruby will be ABI zero.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
PostPosted: Sun May 16, 2021 4:51 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1398
Location: Scotland
Sheep64 wrote:
drogon on Thu 29 Apr 2021 wrote:
I'm in the process of almost abandoning the standard Acorn MOS vectors at $FF80 upwards and moving the whole lot down to $FDxx... ($FExx is hardware IO)


Commodore, Acorn and W65C265 use the same memory locations for vectors. Applying lighthouse protocol, one of these is preferentially unmoved. Personally, I'd abandon page $FF and leave all of it for microcontroller hardware vectors - or anyone brave enough to use it for I/O. For example, jfoucher's Planck uses approximately half of page $FF for I/O. Other CPLD systems do similar. However, I would move an Acorn ABI to page $FB. It feels *wrong* telling an Acorn 6502 application to jump via page $FC, $FD or $FE (FRED, JIM or SHEILA). Likewise for a Commodore ABI in the same address-space, although less so. Therefore, to minimize unease, I suggest:-

  • Hardware indirection vectors working backward from the end of page $FF.
  • Re-located Commodore jump vectors working backward from the end of page $FD.
  • Re-located Acorn indirection vectors working backward from the end of page $FB.

I believe this would be compatible with W65C134, W65C265, Planck, Ruby, Steckschwein and other systems.


I'v'e already had to move some of the "Acorn MOS" vectors in Ruby to cope with the '816. The reason I'm moving them all, lock, stock and whatever from the Acorn $FFxx ones to $FDxx is to cater for the 65c134 (and possibly the '265 although I've no interest in that right now) The '816 has a few more hardware vectors that interfere with the Acorn ones and '134 has many more hardware vectors in $FFxx that interfere with almost all the Acorn ones and I want the same set of software/OS vectors over my 3 Ruby platforms - the '02, '134 and the '816 potentially to be able to run (c02) binarys over all 3 boards without re-assembling from source or patching binaries.

As far as page $FF being used for IO - well, in all Ruby boards, $FFxx is mutually exclusive shared RAM with the board host processor (ATmega 1284p) That's how Ruby boots and communicates with the world - the ATmega take over RAM, populates the reset vector, puts in a minimal bootloader, releases RAM then takes the CPU out of reset. The bootcode copies itself to lower RAM then interacts with the ATmega to load the rest of the OS.

Sheep64 wrote:
drogon on Thu 29 Apr 2021 wrote:
I have a workaround for BBC Basic which is the only "classic" Acorn software I care for right now


Do you transparently patch known binaries? I've suggested similar for Sargon II Chess. I believe that faster processors may look two or three moves further ahead without screwing the weighted score system.


Yes, I transparently patch known binaries by scanning looking for JMP or JSR to the vectors and change the ones that need changing. This works well for BBC Basic but does not work for some other ROMs I've tried. (Mostly because they're expecting a real BBC Micro to run on) For Applesoft, MS BASIC (Commodore Basic 2) and EhBASIC, I patched the sources and re-assembled them.

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Thu May 27, 2021 12:36 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
It is very good to know that processor architecture identification has been implemented even if it is not in common use. Don't worry about other examples if the hardware is not in common use. We are primarily concerned with the most common cases where a raw binary may or may not target 6502. More advanced systems tend to use COFF, IFF, ELF or EXE and therefore able to provide a useful error message without executing the binary.

When a binary runs, I hope that we can implement a multiple step process in the following order:-

  • A sanity check idiom to test processor architecture and exit with error. This is most likely to help people who are not using 6502.
  • Identify legacy host from a table of known vectors. (I initially thought this would be the only step.)
  • Otherwise look for a magic byte sequence at $0100. This is a fairly common practice on 6502 with "CBM80" used to detect Commodore 64 cartridges and a similar system on W65C265.
  • When host is identified, rewrite zero page references.
  • If we're going to rewrite zero page references, may also want to re-locate binary.
  • After binary is re-located and zero page references are good, now have somewhere to store results of processor feature tests.

It is traditional on an Acorn floppy disk system for the user memory low water mark to be $1900. (Yes, 6.25KB in RAM!) Even this was incompatible with some configurations. Whereas, many systems allow binaries to execute from $0200, $0300 or $0400. Therefore, it may be worthwhile to shuffle a binary down in the memory. While this process occurs, it may also be possible to re-link zero page usage. Most specifically, Acorn reserves $00-$7F for system and $80-$FF for language or user. Whereas, Apple allocates $00-$1F for SWEET16. Definitely don't use $00 or $01 because they are used for page banking latches on some Commodore systems. Unfortunately, it is probably quite easy to find three or four systems with no common range within zero page which may be used by an application.

It is not possible to run processor feature tests until the range to store results is determined. It is not possible to determine the range until the host is known. Likewise, it is not possible to write to zero page before the host is known. That means host identification and re-location is not allowed to use any zero page addressing. However, execution in page $01 is allowed. Self-modifying code is also allowed, although it is not the preferred option. As noted by drogon, by the time we get to host identification, we may be able to obtain detailed system information without running weird byte sequences.

I wonder if dynamic patching of a binary incurs false positives or false negatives? To complete the task unambiguously, one bit per byte may be required to flag changes. If the execution address is unknown and memory is tight, it may be preferable to have a decompressor which returns nine or more bits with each invocation. (0-255: no change. 256-511: zero page reference. 512-767: absolute reference.) In the worst case, a binary may be bloated by 1/8 for re-location flags plus re-location routine plus legacy host vector table plus legacy host identification routine plus instruction set identification plus ABI wrappers. Thankfully, the vast majority of this may be overwritten by data when the program runs. In the worst case, maximum program size on Acorn may be reduced from 26KB to 22KB. That remains significantly larger than EhBASIC or Elite. The main problem is constraint on the workflow required to create such a binary. Even here, it cannot be worse than the codec hackery noted by drogon.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
PostPosted: Thu May 27, 2021 1:08 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1398
Location: Scotland
Sheep64 wrote:
It is traditional on an Acorn floppy disk system for the user memory low water mark to be $1900. (Yes, 6.25KB in RAM!) Even this was incompatible with some configurations. Whereas, many systems allow binaries to execute from $0200, $0300 or $0400. Therefore, it may be worthwhile to shuffle a binary down in the memory. While this process occurs, it may also be possible to re-link zero page usage. Most specifically, Acorn reserves $00-$7F for system and $80-$FF for language or user. Whereas, Apple allocates $00-$1F for SWEET16. Definitely don't use $00 or $01 because they are used for page banking latches on some Commodore systems. Unfortunately, it is probably quite easy to find three or four systems with no common range within zero page which may be used by an application.


Just a few minor corrections:

The Acorn MOS has a notion of "PAGE". This is the start of usable RAM. It's variable and utility ROMs can raise PAGE before a language ROM is activated. Typically it starts at $0E00. The standard disc filing system can raise it to $1900, the advanced disk and network filing systems even higher. Many games make assumptions and many games failed to work when the advanced filing system came and/or network filing systems. Ah well.

As for zero page: The OS claims $90 through $FF and left $00 through $8F for language ROMs. Other areas of RAM below PAGE are used by the OS or left for a language. (e.g. $0400 through $7FF is a 1KB region reserved for the current language ROM - BBC Basic uses it for the fast 32-bit integer variables
@% through Z% and other uses) and my BCPL system uses it for the OS "global vector".

If you wanted your own (assembler) code to live in RAM at the same time as BASIC, it was relatively easy to assemble and load your code at PAGE then raise PAGE to hide it, then re-start BASIC - the first things BASIC does is read PAGE and HIMEM (which is the bottom of video RAM) to see how much workspace it has. If you were careful, then using the built-in assembler (part of BASIC) then you could re-assemble the code on the fly based on PAGE at that point then you didn't need to worry about relocation or finding some otherwise unused space to load you code into.

This seemed a very generous use of RAM at the time (c1981) especially when using some of the higher resolution/colour video modes in a 32KB system but when you really wanted to get serious you used a 2nd processor - BASIC then gave you something like well over 40KB for your program to live in but even in the colour text mode (Teletext) you still had over 24KB for your BASIC program and data to live in.

In the port of EhBASIC I have (based on the one generated by floobydust) it uses zero page from $00 through $7F, so it worked very well in my system. I started work on Applesoft but gave up once I had BBC Basic going. I did get MS Basic (in the form of Commodore Basic 2.0) going in it though.

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 28, 2021 5:00 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
This is a devilish puzzle because it is always possible to make it more difficult than you can manage. Three processor architectures of your own choice is relatively easy. Eight is almost impossible. Choosing the common subset of 8080 and Z80 is admirable and should not be ignored. However, 8080 has become a legacy case while Z80 is ongoing.

In another discussion:-

BillG on Fri 28 May 2021 wrote:
org $2000


By Jove! I think you've cracked it!

While I was aware that one processor's opcode could be manoeuvred into being another processor's operand, it hadn't really occurred to me that said operand may be an absolute address. Therefore, judicious choice of execution address may aid opcode selection. Choosing $2000 on 6502 provides a large amount of downward compatibility to KIM-1, VIC20 (with RAM expansion starting at $2000) and other early systems. If I'm correct, the sequence $4C, $BD, $21, $00, $00 will jump to $21BD on 6502/65816, jump to $2100 on 6800/6809 and load $0000 into Z80 registers. This sequence may also be conducive to 68000, x86 or other systems, although they typically don't load raw binaries. It may also be conducive to other processor architectures. Anyhow, I'm considering a layout where:-

Code:
$2000-$201F: Initial fork which must begin with $4C, $BD, $21, $00 and may or may not end with 10 repetitions of $21, $00, $00.
$2020-$204F: Flags held within repetitions of $21, $xx, $xx. Each 16 bit set of flags is more specific: processor architecture, 6502 dialect, operating system requirements and peripheral requirements.
$2050-$20FF: CP/M exit message and table to identify legacy 6502 systems from vectors.
$2100-$21BC: 6800 exit message, 6502 host identification and 6502 feature tests.
$21BD-$21C1: Jump to re-locator or real start of 6502 program.


Variations allow bytecode interpreters across two or more processor architectures. Historically, this case would never occur. However, when it is difficult to obtain less 128KB static RAM, a dual 6502/6800 VTL environment is one of many possibilities. a 6502/Z80 BCPL environment is another possibility.

A 6502 re-locator may be placed at the end of the binary where is it is most convenient for block copying with substitutions to a lower address range. However, a trivial re-locator may only re-write zero page references to be compatible with each operating system's zero page choices. In this lazy case, a memory allocator may start with two blocks. The first block extends from low memory on a given system to $21C1 or a little further. The second block extends from the end of the binary to high memory. This laziness has a hidden cost. There is the obvious problem that the largest possible contiguous allocation is unnecessarily restricted. There is a further problem. Where memory allocation is worst case O(n^2), we begin with n=2 and this may unnecessarily slow subsequent allocations. This is why a full re-locator is preferred. After host identification completes, after feature tests complete, after re-location, none of this functionality is required again. All of this memory can be re-claimed and the result is the largest, fastest contiguous allocation of memory. This scheme has a storage cost. This scheme has an initial delay. This scheme is also quite torturous to implement. However, normal execution may be faster and more capable.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 13 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: