News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Reverse Assembled BASIC 1.1 Source Code

Started by Bread80, 16:37, 05 October 22

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Bread80

I've now completed my project to reverse engineer/unassemble/reverse assemble the BASIC 1.1 ROM. This update involves the final pass of the second half of the ROM to make sure everything is understood, commented and labelled.

Full code at https://github.com/Bread80/Amstrad-CPC-BASIC-Source

This project builds upon disassembly work of others (I'm not aware of the names).

If there's anything you've always wanted to know about how BASIC operates please ask now while I can still remember it.

zhulien

Is there anything different now than the code base I am already using?

zhulien

Any idea where are the basic error codes stored or returned from when a syntax check occurs? 

In particular how does it not return an error from the first keyword of a 2 keyword instruction?

TotO

#3
@zhulien If I'm not wrong, you are using the version done by @arnoldemu and @SyX ?
I don't see any credits here: http://cpctech.cpc-live.com/docs/basic.asm
"You make one mistake in your life and the internet will never let you live it down" (Keith Goodyer)

TotO

#4
@zhulien OK, the Github "licence" said:

QuoteThis repository is built on the work of those who did the original disassembly and reverse engineering. I don't know the names of those individuals or their licencing terms.

So, this repository is "based" on the BASIC ROM documenting work already done by them around 10 years ago.
I don't know if @Bread80 has fixed things, but he has improved a lot the comments.
"You make one mistake in your life and the internet will never let you live it down" (Keith Goodyer)

eto

Quote from: Bread80 on 16:37, 05 October 22If there's anything you've always wanted to know about how BASIC operates please ask now while I can still remember it.
Can I "run" Basic from machine code? E.g. LDIR Basic code from ROM to RAM and then execute "RUN"?

Bread80

Quote from: zhulien on 11:27, 06 October 22Is there anything different now than the code base I am already using?
Lots more comments and labels added. Other than that, I don't know what you're already using. This version *should* be able to be edited and assembled without any bugs. I can't prove that (without fully testing every feature), but I have done tests where I've rearranged the code and assembled and it runs.

If you dig into the includes folder you'll also find full documentation of every system variable/memory address.

Bread80

Quote from: zhulien on 11:30, 06 October 22Any idea where are the basic error codes stored or returned from when a syntax check occurs?

In particular how does it not return an error from the first keyword of a 2 keyword instruction?

Error handling is in the Errors module. Error messages starting at $cd14.

Error codes aren't 'returned'. The interpreter checks for errors as it parsed the tokenised code. If it notices a syntax error it raises it. Once an error is raised the code never returns. Usually it returns to the interpreter (as you'd expect). If there's an error handler then the error handling code executes. If execution is resumed then the current execution address is reloaded from the appropriate system variable.

*Most* two word identifiers are tokenised separately. This for SPEED INK the tokenised code will have a token to SPEED followed for a token for INK. The interpreter calls the subroutine for SPEED. This then looks at the next token and decides what to do based on that. Ie INK executes SPEED INK, WRITE executes SPEED WRITE. An invalid token raises an error. Have a look at SPEED in the Input module at $d4db.

Some two word identifiers, such as ON BREAK are tokenised to a single token. Check out the keyword table at $e44c in KeywordLUTs. 

1) Also note that GOTO and GOSUB can also be written GO TO and GO SUB. The $09 character in the name tells the parser the space is optional.

2) ON GOTO ERROR 0 is a single token. ON ERROR GOTO <line number> is multiple tokens executed by the ON token subroutine. The former is in the EventsExceptions module. The latter in Errors.


Bread80

Quote from: TotO on 12:24, 06 October 22So, this repository is "based" on the BASIC ROM documenting work already done by them around 10 years ago.
I don't know if @Bread80 has fixed things, but he has improved a lot the comments.
I've assembled the code and diffed it against a ROM image to verify there are no differences.

In my firmware work I did correct a couple of bytes that didn't match in the diff. Both of there were in floating point constant data and I'm assuming they were corrupted during the disassembly process. I can't find any notes on such fixes in the BASIC.

Bread80

Quote from: eto on 12:43, 06 October 22If there's anything you've always wanted to know about how BASIC operates please ask now while I can still remember it.
Can I "run" Basic from machine code? E.g. LDIR Basic code from ROM to RAM and then execute "RUN"?
In theory you could call execute_statement_atHL ($de60, Execution module) with the code address in HL (And obviously enabling the ROM). In practice there's a lot of initialisation work which BASIC needs before it's ready to run code.

I'd suggest you'd want to copy and adapt the code at the very start of the ROM (down to version_string_message)(Initialisation module), as well as the section from REPL_Read_Eval_Print_Loop down to and including the call to reset_basic at $co6e (ProgramEntry module)

BTW once BASIC is initialised you could pass in an ASCII string for it to tokenise and execute, as with an immediate mode command line. In that case look at REPL_tokenise_and_execute ($c0cd, Program Entry).

If you get any of this working it would be fascinating to see.

tronic

Quote from: Bread80 on 21:32, 06 October 22
Quote from: eto on 12:43, 06 October 22If there's anything you've always wanted to know about how BASIC operates please ask now while I can still remember it.
Can I "run" Basic from machine code? E.g. LDIR Basic code from ROM to RAM and then execute "RUN"?
In theory you could call execute_statement_atHL ($de60, Execution module) with the code address in HL (And obviously enabling the ROM). In practice there's a lot of initialisation work which BASIC needs before it's ready to run code.
I'd suggest you'd want to copy and adapt the code at the very start of the ROM (down to version_string_message)(Initialisation module), as well as the section from REPL_Read_Eval_Print_Loop down to and including the call to reset_basic at $co6e (ProgramEntry module)
BTW once BASIC is initialised you could pass in an ASCII string for it to tokenise and execute, as with an immediate mode command line. In that case look at REPL_tokenise_and_execute ($c0cd, Program Entry).
If you get any of this working it would be fascinating to see.

Hello,
First, thank you and great work Bread80.
About "run basic from machine code", as far as i remember, T&J/GPA wrote something about it, there :
http://tj.gpa.free.fr/html/coding/sources.htm
http://tj.gpa.free.fr/zip/sources/runbasic.zip
Which is a compilation of examples found...
Some seem to work...
Some not (depending 464/664/6128/plus séries...)
Have a look maybe ?
Best.

Tronic/GPA
https://rasmlive.amstrad.info/




zhulien

Quote from: TotO on 11:56, 06 October 22@zhulien If I'm not wrong, you are using the version done by @arnoldemu and @SyX ?
I don't see any credits here: http://cpctech.cpc-live.com/docs/basic.asm
I actually got about 80% through reverse engineering it myself when @Bread80 reached out saying its done already and pointed me to the git repo. So I used that, it shed a lot of light especially on the crazy error message and thr already comments were invaluable.

Powered by SMFPacks Menu Editor Mod