[abc80] Assembler -> BAC program?

H. Peter Anvin hpa at zytor.com
Tors Juni 26 09:13:42 PDT 2014


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