MacBas95

Saturday 10 November 2012
by  cgh
popularity : 0%

Zip - 94.8 kb
MacBas95
macro-assembleur, moniteur, debugger and sourcer for the SHARP PC-1500 and Tandy PC-2

MACBAS95 - A macro-assembler, monitor, debugger and sourcer for the SHARP PC-1500 and the TANDY PC-2

Copyright 1990-1995-2012 Christophe Gottheimer (see the README file in the MacBas95.zip archive for contact details)

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.

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 dot "." to be compiled, but this dot 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 artifact. When a keyword is found, and a dot 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 careful 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&124;*&mn[,&n&124;*&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 mnemonics used are the Z80 mnemonics and registers names are Z80 register names. This is partly because this makes the assembler more compact.

Register mapping between LH5801 and Z80 :

LH5801 Z80
A A
F F
X BC
Y DE
U HL
XH B
XL C
YH D
YL E
UH H
UL L
P PC
S SP

The following mnemonics are supported:

LH5801 MacBas operands
ADC ADC r|&n
ADC[#] ADC[#] (R)|(&mn)
ADR ADD R
ADI[#] ADD[#] (R),&n|(&mn),&n
AM0 AM0
AM1 AM1
ANI AND. &n
equivalent to ANI A,&n
AND[#] AND.[#] (R)|(&mn)
ANI[#] AND.[#] (R),&n|(&mn),&n
ATP ATP
BII BIT &n
equivalent to BII A,&n
BII[#] BIT[#] (R),&n|(&mn),&n
BIT[#] BIT[#] (R)|(&mn)
SJP CALL. &mn
CDV CDV
CPI CP r,&n
CPI CPA &n
equivalent to CPI A,&n
CPA CPA r
CPA[#] CPA[#] (R)|(&mn)
CIN CPI
DCA[#] DADC[#] (R)
DEC DEC A|r|R
RIE DI
LOP DJC -d|&mn
equivalent to LOP UL,-d|&mn
DCS[#] DSBC[#] (R)
SIE EI
HLT HALT
INC INC A|r|R
ITA ITA
JMP JP &mn
BCH JR +d|-d|&mn
BC[RS]
BH[RS]
BZ[RS]
BV[RS]
JR cc,+d|-d|&mn
LDX LD BC,RR
STX LD RR,BC
LDI LD SP,&nm
LDI LD r,&n
TTA LDA F
LDI LDA &n
LDA LDA r
LDA[#] LDA[#] (R)|(&mn)
LDE[#] LDD[#] (R)
TIN LDI
LIN[#] LDI[#] (R)
NOP NOP
ORI OR. &n
equivalent to ORI A,&n
ORI[#] OR.[#] (R),&n|(&mn),&n
ORA[#] OR.[#] (R)|(&mn)
POP POP A|R
PSH PUSH A|R
REC RCF
RDP RDP
RTN RET
RTI RETI
ROL RL
DRL[#] RLD[#]
OFF ROF
RPU RPU
RPV RPV
ROR RR
DRR[#] RRD[#]
SBI SBC &n
equivalent to SBI A,&n
SBC SBC r
SBC[#] SBC[#] (R)|(&mn)
VEJ
VMJ
SBR &n[,args[,args[,...]]]
VC[RS]
VH[RS]
VZ[RS]
VVS
SBR cc,&n[,args[,args[,...]]]
SEC SCF
SDP SDP
SHL SL
SPU SPU
SPV SPV
SHR SR
ATT STA F
DOES NOT DISASSEMBLE PROPERLY
STA STA r
STA[#] STA[#] (R)|(&mn)
STD STD (R)
SIN STI (R)
AEX SWP
EAI XOR &n
EOR[#] 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:

   A=10
  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,&m
  LD DE,&mn - Assembled as LD D,&n:LD E,&m
  LD HL,&mn - Assembled as LD H,&n:LD L,&m

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,"NUPR"
  43     CPA ASC("Z")+1:JR C,"NUPR"
  44     OR. ASC("a")-ASC("A"):STA (BC)
  45     "NUPR"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 enter &2020 then press 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
(own-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

See the mnemonics table (a couple of instructions not assembling or disassembling properly).

After having used the monitor or debugger, LIST in PRO mode will return to the monitor after pressing up or down arrow. To fix this, just press Shift+CL to disable the monitor/debugger.

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 (over 21% 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

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.