[abc80] Assembler -> BAC program?

Andreas Gustafsson andreas.gustafsson at gmail.com
Tors Juli 3 02:49:32 PDT 2014


Tack för den utförliga förklaringen!

Jag tog en binär och körde igenom din Perl-variant på en Linuxburk på
jobbet, så med den outputten som "facit" och referens, sourcekoden till
Perl-varianten och din förklaring har jag nu lyckats skapa en C-version som
jag kunde bygga och integrera i min Windows "toolchain" för att bygga
ABC80-binärer!

Det här sättet att ladda binärer är väldigt smart, tillåter väldigt mycket
större binärer än min gamla POKE-metod samt tillåter att binären överlappar
var bac-filen laddas.
Som jag förstår det så blir det egentligen så här av det

<6 basic bytes><xxx antal bytes från binären><2 basic bytes>
<6 basic bytes><xxx antal bytes från binären><2 basic bytes>
...
<6 basic bytes><xxx antal bytes från binären><2 basic bytes>
<assemblersnutt>

Assemblersnutten kopierar sedan binär-bytesen till startaddressen, och har
man samma startaddress på binären som där BAC-filen laddas finns det aldrig
någon risk att det blir konflikt, eftersom stället den kopierar från alltid
kommer ligga lite före stället den skriver till. Genialt!
Så nu kan jag ha binärer som sträcker sig från 0xc000 och en bra bit över
0xf000.

/Andreas




2014-06-26 18:13 GMT+02:00 H. Peter Anvin <hpa at zytor.com>:

> On 06/26/2014 08:41 AM, Andreas Gustafsson wrote:
> >
> > Har försökt studera koden som hpa postade, men perl är verkligen inte
> > min hemmabana, så jag har lite svårt att se vad det gör.
> >
>
> Så för att börja från början:
>
> BOFA = systemvariablel på adress 65052 som indikerar var
> BASIC-programmet börjar i RAM.
>
> EOFA = systemvariablel på adress 65054 som indikerar var BASIC-
> programmet slutar i RAM.
>
>
> a) .BAC-filer består av block på 253 bytes.  Första byten i första
> blocket är 0x82, block avslutas med 0x01 för sista blocket eller 0x00 om
> det kommer mer data.  Följande bytes spelar ingen roll (mitt program
> skriver 0x00 bytes, men BASIC-tolken lämnar vad som nu fanns i buffern.)
>
> Resten av data är BASIC-rader; en rad kan så vitt jag vet inte delas
> mellan block.
>
> Byten 0x82 lagras ej i minnet, inte heller lagras 0x00 och bytarna
> mellan blocken, däremot lagras 0x01 i minnet (EOFA pekar alltid till
> denna byte.)
>
> Subrutinen genpad() fyller ut ett block om det behövs.
>
>
> b) Formatet på varje BASIC-rad är: 1 byte längd, 2 bytes radnummer,
> internkoder, 0x0d.  Om längden är 0x01 är programmet slut (se ovan.)
>
> Subrutinen bacstmt() formatterar en BASIC-rad.
>
>
> c) Den första raden i programmet är:
>
> Z%=CALL(PEEK(65054%)+SWAP%(PEEK(65055%))-<loader offset>)
>
> Internkoderna är:
>
> 83 C1 F1 5A 00 BB C7 1E FE CE 36 C7 1F FE CE 36 CE 34 F5 C7 xx xx F8 CE
> 3A B7
>
> Internvariabeln på adress 65054 är EOFA, som pekar på 0x01-byten i
> slutet at programmet.  <loader offset> är alltså hur många bytes innan
> slutet av programmet som vi ska hoppa till.
>
>
> d) Varje rad innehåller internkoderna för ett stränguttryck.  Det är
> helt enkelt den kortaste sekvens som jag har hittat som inte
> BASIC-tolken muckar med när man startar RUN (BASIC-tolken hoppar inte
> över REM-satser, t.ex.):
>
> CB 22 xx <bytes> BB
>
> ... där xx är antalet bytes.
>
> Större delen av programmet är helt enkelt rad på rad på rad med sådana
> stränguttryck med okodade data.
>
>
> e) Den näst sista raden är ett END-statement:
>
> 86 8A
>
> Assemblerrutinen som kopierar data känner igen den helt enkelt för att
> det är för kort för att kunna vara ett stränguttryck.
>
>
> f) Sista raden innehåller ett stränguttryck som innehåller
> assemblerrutinen som ska kopiera data till det korrekta stället.
>
> Det finns två varianter:
>
> Den enkla varianten, som laddar på en fast adress:
>
>
> http://git.zytor.com/?p=fpga/abc80/abc80.git;a=blob;f=data/bacldr.asm;hb=HEAD
>
> Den mera komplicerade varianten skriver över själva programmet (fr.o.m.
> adress BOFA) och sedan går igenom en lista på adresser som behöver
> justeras beroende på laddningsadressen (s.k. relokeringar):
>
>
> http://git.zytor.com/?p=fpga/abc80/abc80.git;a=blob;f=data/bacldr2.asm;hb=HEAD
>
> Eftersom det finns två varianter som är olika långa så kan värdet på
> <loader offset> under punkt (c) variera.  <loader offset> = längden på
> assemblersnutten plus 2 för byten BB som avslutar stränguttrycket och 0D
> som avslutar BASIC-raden.
>
> Det finns flera värden i assemblerkoden som behöver justeras:
>
> 1. Avståndet från BOFA till första raden (= längden på rad 1 under punkt
> c).
>
> 2. Startadressen (entrypoint)
>
> 3. För den enkla varianten, laddadressen.
>
> #1 skulle man lätt kunna eliminera, förstås.
>
>         -hpa
>
>


More information about the ABC80 mailing list