MACBAS95 - A macro-assembleur, moniteur, debugger and sourcer for
           the SHARP PC-1500 and the TANDY PC-2

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

MACBAS95 is a software loaded and running in the PC-1500/PC-2.

BE CAREFUL ! MACBAS95 is a powerful software to write and execute Machine
Language programs. Misusing instructions or calling anywhere may result
in a whole memory lost. Crashes may occurs: in these case, press the RESET
button in the back of computer using a pen during a couple of seconds.

------------------------------- WARNING ----------------------------------
WARNING ! Important note : MACBAS95 is NOT compatible with the CE-150 or
the CE-158, because the MACBAS95 system data is stored at the same area
than the pointers of the CE-150 and CE-158 devices.

Before to print or use the CE-150/CE-158, they should be initialized.
After a print or use of the CE-150/CE-158, the pointers and registers of
MACBAS95 should be reassigned with ASM or REGS.
--------------------------------------------------------------------------

I am not responsible for any damages caused by using MACBAS95 or by any
programs developped with this utility.

0. Contents

COPYING		- The GPL v2 licence
README		- This file
macbas95.asm	- The dump done by lhTools-0.2
macbas95.bin	- The binary image
macbas95.frag	- The fragment file to use with lhTools-0.2
macbas95.keyw	- Keyword file to decompile BASIC image with lhTools-0.2
macbas95.wav	- The wav file to be played directly from a computer


1. Installation

MACBAS95 requires a CE-161 or CE-163 memory module. It is not relocable
and it is stored from &00C5 to &1FFF.

MACBAS95 requires also a new ROM to works. To know if MACBAS95 is compatible, do
	PEEK &E2B9
If you get 56, MACBAS95 will run on your PC, else it will be not possible to use
it.

First, reserve space for MACBAS95 by doing a NEW &2000

Play the macbas95.wav file and type CLOAD M on the PC-1500/PC-2.
When loading, the banner MACBAS 95 DEC30 is shown on the display.
After 9 minutes, the software is loaded.

To become operational, the following instructions have to typed on the
PC-1500/PC-2. They are still active after a power off and need only to
be typed if a RESET is performed.

    POKE &785B,&1B,&5D
    POKE &79D1,&8
    POKE &79D4,&55

When done, juste do DEF OFF. This action will perform a checksum computation
of the MACBAS95 code and insure that the code is not corrupted. This has to be
done each time a RESET is performed or a crash occurs.


2. New BASIC keywords

In this document, the following conventions are used:

&n	: A 8-bits value or offset = 0..255 or &0..&FF
&mn	: A 16-bits value or address = 0..65535 or &0..&FFFF
(&mn)	: Indirect 16-bits address = (0)..(&65535) or (&0)..(&FFFF)
"..."	: A string or a text between double quote
*&mn	: A offset between the current assembler address and the address &mn
+d|-d	: A forward or backward 8-bits offset
r	: A 8-bits register = B,C,D,E,H,L
rH	: A high 8-bits register = B,D,H
rL	: A low 8-bits register = C,E,L
R	: A 16-bits register = BC,DE,HL
(R)	: Indirect 16-bits register = (BC),(DE),(HL)
RR	: A 16-bits register = BC,DE,HL,PC,SP
RRr	: All 16-bits register or the accumulator = A,BC,DE,HL,PC,SP
RRR     : All registers = A,F,BC,DE,HL,PC,SP
ccc	: A condition = C,Z,V,H,NC,NZ,NV,NH,=,<>,>=,<,<=,>
cc	: A contition = C,Z,V,H,NC,NZ,NV,NH,=,<>,>=,<
[]	: Optional argument
|	: Choice between arguments
inst#	: Specify a second page instruction
[#]cc	: Specify that the offset will go outside 255 bytes and the assembler
	  use an absolute branch
...	: Eventually repeat the same arguments

Some new keywords are followed by a . to be compiled, but this . does not appear
in the decompiled line. This is due to the fact that some keywords have the same
name or the same leading letters between the main BASIC and MACBAS95. To avoid to
overload the display, I used this artefact. When a keyword is found, and a .
immediately follows it, it will be taken into the other table. The main BASIC
table is looked first, this permits to have RET mixed with RETURN, STA with STATUS.
The keywords common to both tables are: AND CALL END IF OR. Be carefull with CALL !

2.a. Assembler directives


Note that this keywords are only usable while running the assembler and should
be entered in PRO mode.

ASM <start-code>,<end-code>[,[<start-symb>,<end-symb>][,<store-code>]
	- Activate the assembler. Instructions after this directives will be
	  assembled. If some arguments are not specified, the previous values
	  are used.
END.	- Finish the assembler. When running a program, instructions outside
	  the block ASSEMBLE .. END. will raise an error.
DEFS "symbol-name"[=&mn]
	- Defines a symbols to the given value &mn. If no value is specified
	  the current assembler address (i.e THIS) is taken.

2.b. Assembler variables

WPC	- Function returns the current assembler address
PASS	- Function returns the current pass of the assembler, i.e, 1 for the
	  first pass, 2 for the second, 0 if the assembler is not active.

2.c. Assembler data

BYTE &n|*&mn[,&n|*&mn[,...]]	- Store 8-bits values
WORD &mn[,&mn[,....]]		- Store 16-bits values
TEXT "<text>"[,"<text>"[,...]]		- Store text strings

2.d. Values

HIGH &mn - Returns the high 8-bits value from a 16-bits value.
LOW &mn  - Returns the low 8-bits value from a 16-bits value.

2.e. Structured code

IF. [#]cc <TRUE-code> [ELSE <FALSE-code>] ENIF
BEGIN <loop-code> UNTIL [#]cc|DJC
BEGIN <condition-code> WHILE [#]cc <loop-code> REPEAT

If #cc is given as condition, this will inform the assembler that the jump
will go over the 255 bytes limit and tell the assembler to use absolute
jumps instead of relatives.

See some examples in section 2.j.

2.f. Symbols

GETS "symbol-name"	- Return the value of the symbol if it is defined
SYMBOL ON [&mn]		- Active the symbol table (at &mn if given)
SYMBOL OFF		- Deactivate the symbol table
SYMBOL LIST [&mn]	- List all symbols on the screen. Press (down-arrow)
			  to list the next symbol, ON/BREAK to exit.

2.g. BASIC program

RENUM [number][,increment]	- Renum the BASIC program starting at the
				  number given (or 10 if missing) and add the
				  given increment (or 10 if missing)
LINK				- Modify the pointer to add a new BASIC program
				  without clearing the previous (like MERGE)
UNLINK				- Merge the both programs in the BASIC memory

SRCS <start-code>,<end-code>[,<start-data>,<end-data>[,<symbol>[,line[,increment]]]]
	- Build a BASIC program using the ML code from <start-code> to <end-code>
	  using the symbol table at <symbol> (or the current if missing), create a
	  byte or text area from <start-data> to <end-data> if specified. The first
	  line has the line number specified (or 10 if missing) and increment each
	  line by the increment specified (or 10 if missing).
	  When symbols are found into the table, the disassembler will use them.
	  When making a jump (absolute or relative) without any symbols found, the
	  disassembler will build a symbol "Lnnn" where nnn is incremented at each
	  new symbol.
	  Note that LINK and UNLINK are useful with SRCS.

2.h. ML execution

REGS RRR=&mn|RRR TO var[,RRR=&mn|RRR TO var[,...]]
	- Load register RRR with the value &mn or save the register value to the
	  BASIC variable var.
EXEC [TRON] &mn[,SP][;[A][,[BC][,[DE][,[HL]]]][;[varA][,[varBC][,[varDE][,[varHL]]]]]]
	- Launch execution of the ML program at the address &mn, with optionally
	  specifing the stack SP, optionally storing the given value to A, BC, DE and HL.
	  When the execution ends, optionally the value of the registers A, BC, DE and HL
	  may be saved into the BASIC variables varA, varBC, varDE and varHL.
	  If TRON is given, the execution does not start, but the debugger is activated.
	  When the debugger is active, pushing ON/BREAK while the execution will break
	  the program, showing BREAK AT &mn. Also, if the stack goes outside its space,
	  the program will abort by ERROR AT &mn.
	  See the Keyboard driver section 3. below for further explanation about the
	  debugger.
EXEC CONT [&mn] - Continue execution after a break, at the address specified if any
EXEC TROFF	  - Deactivate the ML debugger
EXEC RUN &mn[;args,....]
	- Launch execution of the ML program at the address &mn, but the arguments may
	  be be parsed as any BASIC functions or commands. This is useful to implement
	  new BASIC commands.

2.i. LH5801 mnemonics

The mnemonics are assembled in both RUN (immediate mode) or PRO modes (execute a RUN to
starts the assembler). When the assembler is working, more functionnalities, like define
symbols or the structured programmation are available.

The following mnemonics are supported:
    ADC      r|&n
    ADC[#]   (R)|(&mn)
    ADD      R
    ADD[#]   (R),&n|(&mn),&n
    AM0
    AM1
    AND.     r|&n 
    AND.[#]  (R),&n|(&mn),&n 
    AND.[#]  (R)|(&mn) 
    ATP
    BIT      &n
    BIT[#]   (R),&n|(&mn),&n
    BIT[#]   (R)|(&mn)
    CALL.    &mn 
    CDV
    CP       r,&n
    CPA      r|&n
    CPA[#]   (R)|(&mn)
    CPI
    DADC[#]  (R)
    DEC      A|r|R
    DI
    DJC      -d|&mn
    DSBC[#]  (R)
    EI
    HALT
    INC      A|r|R
    ITA
    JP       &mn
    JR  [cc,]+d|-d|&mn
    LD       BC,RR
    LD       RR,BC
    LD       SP,&nm
    LD       r,&n
    LDA      r|F|&n
    LDA[#]   (R)|(&mn)
    LDD[#]   (R)
    LDI
    LDI[#]   (R)
    NOP
    OR.      r|&n 
    OR.[#]   (R),&n|(&mn),&n 
    OR.[#]   (R)|(&mn) 
    POP      A|R
    PUSH     A|R
    RCF
    RDP
    RET
    RETI
    RL
    RLD[#]
    RPU
    RPV
    RR
    RRD[#]
    ROF
    SBC      r|&n
    SBC[#]   (R)|(&mn)
    SBR [cc,]&n[,args[,args[,...]]]
    SCF
    SDP
    SL
    SPU
    SPV
    SR
    STA      r|F
    STA[#]   (R)|(&mn)
    STD[#]   (R)
    STI[#]   (R)
    SWP
    XOR      r|&n
    XOR[#]   (R)|(&mn)

Note that the mnemonics and the commands BYTE, WORD and TEXT can work in live
mode, directly on keyboard.

The registers A,B,C,D,E,H,L,F,BC,DE,HL,PC,SP,(BC),(DE),(HL) are different from the
corresponding BASIC variable. If you want to use the value of BASIC variable, you
may do it with 0+... to avoid an incorrect instruction:
   A=10
   LDA A (will be rejected by the assembler)
do instead:
   LDA 0+A

The SBR mnemonics support all BASIC macros, and expect correct arguments depending
of the SBR (&n) called. Here is the syntax of each SBR (&n):
   &00,&n,&n,+d
   &02,&n,&n,+d
   &04,+d
   &08,+d
   &1A,+d
   &26,+d
   &28,+d
   &2C,+d
   &2E,+d
   &C8,+d
   &DE,+d
   &10,&n
   &1C,&n
   &CA,&n
   &CC,&n
   &D4,&n
   &D6,&n
   &0E,&n,+d
   &CE,&n,+d
   &D0,&n,+d
   &2A,&n,&n
   &D2,+d,&n
   &F4,&mn
   &F6,&mn
   &34,&i,&n0,+d0,&n1,+d1...,&ni-1,+di-1
   &C2,k,+d
   &C4,k,+d
       k is 8-bits value if k < &E0, or a 16-bits value if k >= &E000

Some instructions are specific to MACBAS95:
   LD BC,&mn - Assembled as LD C,&n:LD B,&n
   LD DE,&mn - Assembled as LD D,&n:LD E,&n
   LD HL,&mn - Assembled as LD H,&n:LD L,&n

The conditions <= and >are supported:
   JR <=,+d  - Assembled as JR Z,+d:JR NC,+d
   JR >,+d   - Assembled as JR Z,+2:JR C,+d 

2.j. Some examples

First we will reserve some space from &2000 to &21FF for ML and symbols:
   NEW &2200

Type the following code (note that the indentation is here only to have a
pretty view):
   10 ASM &2000,&20FF,&2100,&21FF
   20 "STRLOWER"DEC L
   30 IF. C
   40   BEGIN
   41     LDA (BC)
   42     CPA ASC("A"):JR NC,"NUPPER"
   43     CPA ASC("Z")+1:JR C,"NUPPER"
   44     OR. ASC("a")-ASC("A"):STA (BC)
   45     "NUPPER"INC BC
   46   UNTIL DJC
   50 ENIF
   60 SCF: RET
   70 END.

Do a RUN, and wait for 3 seconds. The code will be assembled.
In PRO mode, doing DEF (down-arrow) will show:
   2000="STRLOWER":DEC L
Use (down-arrow) to see the next instruction:
   2001:JR NC,&2012

Now execute it (A$ is at address &78C0 and the string has 16 characters).
   A$="TH!S 1s MaCBaS95"
   EXEC &2000;,&78C0,,16
   A$
and you will show: th!s 1s macbas95

You can execute it step by step by doing EXEC TRON &2000;,,&78C0,,16

Now, do NEW to clear the current program, and call the sourcer SRCS:
   NEW
   SRCS &2000,&2013,,&2100
And now do LIST and use the (down-arrow) to show the ML program sourced:
   LIST
   10:"STRLOWER":DEC L
   20:JR NC,"L002"
   30:"L001":LDA (BC)
   40:CPA &41
      ...etc...
   130:RET

Another example with an FOR..NEXT loop:
   10 ASM &2020,&20FF
   20 LDA &21
   30 BEGIN
   40   CPA &80
   50 WHILE <
   60   STI (BC)
   70   RCF:ADC &10
   80 REPEAT
   90 SCF:RET
   100 END.

This program will fill the string pointed by BC with "!1AQaq"
   B$=""
   EXEC &2020;,&78D0
   B$

Go in PRO mode, and do
   &2020 DEF (up-arrow)
You see:
   2020:LDA &21
Do
   LDA &24
You see:
   2020:LDA &24

Rerun the ML program:
   C$=""
   EXEC &2020;,&78E0
   C$
and see $4DTdt
You can also do:
   D$=""
   REGS BC=&78F0,A=&26
   EXEC &2022
   D$
and you see &6FVfv

3. The keyboard driver

With MACBAS95 a full enhanced keyboard driver is provided. There are modes
with this new driver

3.a. The normal mode

With this new driver, all keys have autorepetition, also direct or SHIFT or
DEF key are pressed.

In all modes (RUN, PRO, RESERVE), the following key extension are usable:

DEF OFF		- Compute the checksum of MACBAS95 and raise a RESET if code is
		  code is corrupted
DEF CL		- Clear the line from the cursor position to the end of line
DEF MODE	- Jumps from : to :
DEF (left-arrow)- Goto beginning of the line
DEF (right-arrow)- Goto end of the line
SHIFT INS	- Activate or deactivate the auto-insertion mode

3.b. The debugger/monitor keyboard

When in PRO mode, the following key extension are usable:

DEF (up-arrow) 	- Read the address in the input buffer (like AREAD) and start
		  disassembling at the given address
DEF (down-arrow)- Start disassembling at the last address, or at the start
		  address of the assembler, ie, <start-code>
(up-arrow)	- One instruction, 8 bytes or 16 characters backward
(down-arrow)	- One instruction, 8 bytes or 16 characters forward
(left-arrow)	- One byte backward
(right-arrow)	- One byte forward
DEF RCL		- Show the general registers PPPP:BBCC DDEE HHLL AA FF
SHIFT RCL	- Show the status registers PPPP:SSSS aaaaaaaa hvzic
		  with aaaaaaaaa the binary represention of A and hvzic the
		  binary representation of F, lower case if cleared, upper case
		  if set.

If the disassembler is started:

DEF MODE	- Switch between instruction and text display
SHIFT MODE	- Switch between instruction and byte display

When in RUN mode, after the debugger was activated by EXEC TRON

(up-arrow)	- Show the current instruction
(down-arrow)	- Execute the current instruction
DEF (up-arrow)	- Shows the stack PPPP->xx yy ...()
DEF (down-arrow)- Execute a CALL as a standalone instruction
DEF (dbl-arrow)	- Execute up to a RET instruction
SHIFT (dbl-arrow)- Continue execution
SHIFT CA	- Deactivate the debugger


4. Assembler errors

100	- The assembler is already running
101	- The assembler is not running
102	- Code area and symbol tables overlaps
103	- No END. found while assembler is running
104	- END. does not return to ASM
105	- The code differs between pass 1 and 2
106	- Code goes outside its space (>code-end)
107	- Symbols goes outside the table (>symbol-end)
108	- Structured macro stack not empty at the end
109	- Structured macro stack empty or full up
110	- Incorrect structured macro stack pop
111	- Condition cc or ccc expected
112	- Incorrect condition cc for SBR or structured macros
113	- Relatif jump greater the 255 bytes
114	- 8-bits value expected, 0..255
115	- 16-bits value expected, 0..65535
116	- Incorrect instruction
117	- Incorrect instruction in second page &FD
118	- EXEC can not return register value in TRON mode
119	- SRCS overlaps
120	- Unknown symbol
121	- Redefined symbol
122	- Invalid character in symbol name
123	- Symbol value differs between pass 1 and 2


5. Known bugs
    
None at this time, but certainly some...


6. To do
    
- Correct bugs !


7. Differences between previous and next release

Yes ! 3 release of MACBAS exists. The MACBAS 1.0 in 1990/1991 and MACBAS 3.0
in 1999 but never really tested and I have found bugs several days ago

7.a. MACBAS 1.0 vs MACBAS95

- The register names are X,Y,U,P,S instead of BC,DE,HL,PC,SP
  So XH,XL,YH,YL,UH,UL stands for B,C,D,E,H,L. Why ? Just because assembler
  sources are smaller... in the way I program !
- The debugger is not embedded inside the keyboard driver, but the BASIC
  command: DBGS [&mn] which is less useful and integrated.
- WPC is THIS, GETS is DEEK and the others changes are:
      #INLINE	is ASSEMBLE
      #DEFINE	is DEFS
      #IF	is IF.
      #ELSE	is ELSE
      #ENDIF	is ENIF
      #BEGIN	is BEGIN
      #UNTIL	is UNTIL
      #WHILE	is WHILE
      #REPEAT	is REPEAT
      #BYTE	is BYTE
      #WORD	is WORD
      #TEXT	is TEXT
      #END	is END.
- REGS does not exists.
- The assembler works only while running program. It is not possible to
  assemble in live.

7.b. MACBAS 3.0 vs MACBAS95

- The register names are the same as in MACBAS 1.0, for the same reason.
  Even if I prefer the Z80-like register naming...
- WPC is THIS, LINK and UNLINK are PRGM LOCK and PRGM UNLOCK.
- A new keyword BKPT which insert a call to the debugger breakpoint entry
  into the code. Very useful for debugging.
- Some space optimization realized, but not witha real success as I see
  the number of regressions.
- Currently work-in-progress, the patch 1 is on tests, but no so stable and
  mature to be diffused.

7.c. MACBAS next...

Currently, I have no time to start a new development of this size and with
this difficulty. Perhaps, the next will be just the MACBAS 3.0 with patches
to correct bugs and others very small things...

7.d. And why MACBAS95 ?

Because, it is the more mature and this I prefer: I found better to use
single letter for 8-bits register, and 2 letters for 16-bits, like in Z80
naming. Also, I found the debugger embedded inside the keyboard very useful
and let switch from ML to BASIC.


8. Copyright and license
    
Copyright 1990-1995-2012 Christophe Gottheimer <cgh75015@gmail.com>
    
MACBAS95 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.

