ASSEMBLER - A small assembler for the SHARP PC-1500/A and the TANDY PC-2

This code is expected to run in the SHARP PC-1500/A and the TANDY PC-2.

                          !!!!BE CAREFUL !!!!
This software is provided to help in ML (Machine Language) development.
Writing and executing ML programs may raise severe crashes, resulting in
memory cleared. Be sure to save your important job before launching ML
programs.

This version is still in pre-alpha release. It is not fully mature and bugs
are present.

1. Installation

It is relocatable by assembler.c program provided. For an easier use,
the binaries and WAV images for several addresses are provided as follow:
    ASSEMBLER-00C5.WAV : At address 0x00C5 - Need a CE-161 or CE-163 module
    ASSEMBLER-0100.WAV : At address 0x0100 - Need a CE-161 or CE-163 module
    ASSEMBLER-20C5.WAV : At address 0x20C5 - Need a CE-159 module
    ASSEMBLER-2100.WAV : At address 0x2100 - Need a CE-159 module
    ASSEMBLER-38C5.WAV : At address 0x38C5 - Need a CE-155 module
    ASSEMBLER-3900.WAV : At address 0x3900 - Need a CE-155 module
    ASSEMBLER-40C5.WAV : At address 0x40C5 - In RAM
    ASSEMBLER-4100.WAV : At address 0x4100 - In RAM

The assembler needs 1390 bytes. Depending of the image you want to load,
do the following:
    NEW &0633 for ASSEMBLER-00C5.WAV
    NEW &066E for ASSEMBLER-0100.WAV
    NEW &2633 for ASSEMBLER-20C5.WAV
    NEW &266E for ASSEMBLER-2100.WAV
    NEW &3E33 for ASSEMBLER-38C5.WAV
    NEW &3E6E for ASSEMBLER-3900.WAV
    NEW &4633 for ASSEMBLER-40C5.WAV
    NEW &466E for ASSEMBLER-4100.WAV
and load the ASSEMBLER with CLOAD M
After 1 minute and 50 seconds the ASSEMBLER is loaded.

2. Image generation

If you want to install the ASSEMBLER to another location, use the assembler
program.
Compile assembler:
    gcc -o assembler assembler.c
Run the assembler with the new location wanted in hexadecimal without 0x:
    ./assembler [mylocation]
If no location is given, the default RAM base address 0x40C5 is taken.
Follow the installion directives printed while patching the code.
You will get a binary image called ASSEMBLER-mylocation.BIN
To build a WAV file, you need to call bin2wav as follow:
    bin2wav ASSEMBLER-mylocation.BIN ASSEMBLER-mylocation.WAV T:BIN PC:1500 A:0xmyloaction S:5 N:ASSEMBLER-mylocation
The NEW &mylocation+1390 address is printed.

In the following example, we build the ASSEMBLER for the address 0x1234:
    ./assembler 1234
    Relocating ASSEMBLER code to 1234
    Written ASSEMBLER-1234.BIN, 1390 bytes, checksum 6638
    Call bin2wav ASSEMBLER-1234.BIN ASSEMBLER-1234.WAV T:BIN PC:1500 A:0x1234 S:5 N:ASSEMBLER-1234
    Do a NEW &17A2 on the SHARP PC-1500/A or TANDY PC-2
    Call points:
            CALL &1234 -> Set address
            CALL &1236 -> Get address
            CALL &1238 -> Run assembler

Note the checksum printed. In case of crash, it may be useful to check the integrity of
the ASSEMBLER.
Here is the checksums for the given images:
    ASSEMBLER-00C5.BIN  checksum 6C9B
    ASSEMBLER-0100.BIN  checksum 650C
    ASSEMBLER-20C5.BIN  checksum 723B
    ASSEMBLER-2100.BIN  checksum 6AAC
    ASSEMBLER-38C5.BIN  checksum 7673
    ASSEMBLER-3900.BIN  checksum 6EE4
    ASSEMBLER-40C5.BIN  checksum 77DB
    ASSEMBLER-4100.BIN  checksum 704C

3. Use it

The ASSEMBLER consists of 3 CALLs to be called from the BASIC:
    CALL start+0,X   : Set the code address
    CALL start+2,X   : Get the code address
    CALL start+4,X$  : Run assembler

The immediate assemblage address is stored in the address &79ED &79EE

In the following examples, we assume the ASSEMBLER at &40C5 (ASSEMBLER-40C5.WAV)
To set the assemblage pointer to 0x4700, do (X may be any numeric variable)
    X=&4700
    CALL &40C5,X

To retrieve the current assemblage pointer, do (V may be any numeric variable)
    CALL &40C5,V

To assemble at the current assemblage pointer, do (S$ may be any string variable)
    S$="/CALL &E669 /RET"
    CALL &40C9,S$
Note that after this command, the assemblage pointer is incremented to &4704

If a long assembly code need to be processed, use DIM to declare a long string variable
    DIM TT$(0)*80
    TT$(0)="/LDA &00 /DEC A /JR- NZ,&03 /CALL &E669 /RET"
    CALL &40C9,TT$(0)

    TT$(0)="/LD B,$B /LD C,&43"
    CALL &40C9,TT$(0)

For ASSEMBLER, each mnemonic should start with /.
A hexadecimal value or array of values should start with &
A charcater or a string should start wit $
For example:
    N$="&BEE6699A"
    CALL &40C5,N$
will be the same as "/CALL &E669 /RET".

    N$="$PC-1500"
    CALL &40C5,N$
will result in writting the string "PC-1500".

The valid registers are:
    A F B C D E H L BC DE HL PC SP (BC) (DE) (HL)

The valid contions are:
    Z C H V NZ NC NH NV

The following mnemonics are know from ASSEMBLER:
    ADC ADD DADC SBC DSBC CPA CPI CP INC DEC
    AND OR XOR BIT SCF RCF SLD SRD SWP SL SR RL RR
    LDA STA LDI LDD LD STI STD
    JP JR+ JR- DJC CALL RET RTI SBR
    RPV SPV NOP SPU RPU ADA PUSH POP AM0 AM1 CDV
    ATP INA SDP RDP EI DI HALT OFF

The follwoing convention are used:
    &n     : An immediate 8-bits value (&00..&FF)
    &mn    : An immediate 16-bits value (&0000..&FFFF)
    (&mn)  : Indirect immediate 16-bits value
    r      : 8-bits register = B C D E H L
    rH     : High 8-bits register = B D H
    rL     : Low 8-bits register = C E L
    A      : Accumulator
    F      : Flags (status) register
    R      : 16-bits register = BC DE HL
    RR     : All 16-bits registers = BE DE HL PC SP
    (R)    : Indirect 16-bits register = (BC) (DE) (HL)
    SP     : Stack-Pointer register
    [cc,]  : An optional condition = Z C H V NZ NC NH NV
    [#]    : Optional second table access
    |      : Exactly one choice
    ,      : Several arguments

Syntax:
    ADC      r|&n
    ADC[#]   (R)|(&mn)
    ADD[#]   (R),&n|(&mn),&n
    DADC[#]  (R)
    SBC      r|&n
    SBC[#]   (R)|(&mn)
    DSBC[#]  (R)
    CPA      r|&n
    CPA[#]   (R)|(&mn)
    CPI
    CP       r,&n
    INC      A|r|R
    DEC      A|r|R
    AND      r|&n
    AND[#]   (R)|(&mn)
    AND[#]   (R),&n|(&mn),&n
    OR       r|&n
    OR[#]    (R)|(&mn)
    OR[#]    (R),&n|(&mn),&n
    XOR      r|&n
    XOR[#]   (R)|(&mn)
    BIT      &n
    BIT[#]   (R)|(&mn)
    BIT[#]   (R),&n|(&mn),&n
    LDA      r|F|&n
    LDA[#]   (R)|(&mn)
    STA      r|F
    STA[#]   (R)|(&mn)
    LDI
    LDI[#]   (R)
    LDD[#]   (R)
    LD       r,&n
    LD       BC,RR
    LD       RR,BC
    LD       SP,&nm
    STI[#]   (R)
    STD[#]   (R)
    JP       &mn
    JR- [cc,]&n
    JR+ [cc,]&n
    DJC      &n
    CALL     &mn
    SBR [cc,]&n
    ADA      R
    PUSH     A|R
    POP      A|R

The other mnenomics does not require arguments.

4. Errors

ERROR 11  : The string variable is not specified or is not a string.
ERROR 36  : The expected value is not a valid hexadecimal &n or &mn or &nmp...
ERROR 250 : An error occurs when assembling.

5. Known bugs

The instruction /LDA x wher x is an ascii code, ie, $x should be given alone and
a $ should finish the string:
    T$="/LDA $0$"
    CALL &40C9,T$

6. To do

- Correct bugs !
- Add a facility to give an address to JR-, JR+ or DJC.
- Improve the assembler.
- Variables or symbols.

7. Copyright and license

Copyright 1989-2012 Christophe Gottheimer <cgh75015@gmail.com>

ASSEMBLER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License version 2 as published by the Free
Software Foundation.  Note that I am not granting permission to redistribute
or modify nsimII under the terms of any later version of the General Public
License.

This program is distributed in the hope that it will be useful (or at
least amusing), but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along with
this program (in the file "COPYING"); if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
