×   Main Menu ALL The 8BS News Manuals (New menu) Links Worth a Look Tools Disc and Basic Webring Site Map 8BS Guestbook Old Guest Book Me The Barnsley Rovers   
8-Bit Software

The BBC and Master Computer Public Domain Library

8920 '[' Begin Assembly

Submitted by Steve Fewell

Description:

Get the next non-space character.
If the character is ']' (end assembly character) then [&891A] Decrement A (to #&FF), set the OPT flag (location
&28) to A (#&FF) and jump to &900B to process the next BASIC language statement.

Call &9BBC to add Y (the BASIC Text pointer A offset) to the BASIC text pointer address (&0A-&0B) and reset
the PTR A offset to 1; and then check whether an ESCAPE keypress condition has occurred, and process it if it has.
Decrement the PTR A offset to 0.

Call routine &89EB to analyse, validate and assemble the current Assembly Statement (pointed to by BASIC text pointer A).

Decrement the PTR A offset so that BASIC text pointer A points to the Statement terminator character.
If bit 0 of the OPT flag (&28) is clear then no listing is required, so skip the listing routine and jump to &89AE.

[&8936] Produce a listing for the Assembled statement
The line listing will have the following layout:
EXEC B1 B2 B3 LABEL---- TEXT

Where:
* EXEC is the execution address (4 hex digits)
* B1 is the first 6502 Machine Code byte (usually the Instruction Opcode (unless an EQU-command is used)) (2 hex digits)
   (or 2 spaces if the statement doesn't assemble into any actual Machine Code bytes).
* B2 is the second 6502 Machine Code byte (or 2 spaces if no second byte is present) (2 hex digits)
* B3 is the third 6502 Machine Code byte (or 2 spaces if no third byte is present) (2 hex digits)
* LABEL is any label (e.g. '.xxx') that preceeded the assembly statement (minimum of 9 characters wide - right padded with
   spaces, but the LABEL field will be longer if the label name is more than 9 characters wide).
* TEXT is the actual unassembled text (e.g. 'LDA#SIN(2.345)') (this field has no width limit).

Note that the EQUS and EQUD assembly mnemonics may use more than 3 bytes, and as such, the bytes will be listed in groups
of 3, each group being displayed on a new line. The execution address will only be output on the first line. The label and
text will be shown on the last line.

Set location &3F to the value of COUNT (&1E) + 5. This stores what the position on the current output line would be
after the execution address (below) has been printed.

The (EXEC) Execution address (&37-&38) is output as follows:
* Set A to the Execution address MSB (from location &38) and call routine &BD6C to output the 2-digit value (in A).
* Set A to the Execution address LSB (from location &37) and call routine &BD8F to output the 2-digit value (in A)
  followed by a space.

Set X to #&FC.
Set location &38 to the length of the Assembly Mnemonic (in number of bytes); as follows:
* Set &38 to the value of &39 (number of bytes used by Assembly Statement (which is usually 1, 2, 3, 4 or &FF))
* If &39 is a negaive value then a the Mnemonic was a String value ('EQUS'), so set the length (&38) to the SWA
  length (&36).

If &38 is not 0 then the Assembly statement contains some bytes (B1, B2, B3, etc...), which are displayed as follows:
Set Y (physical location byte number) to 0.
[&8954] Increment X
If X has reached 0 (i.e. after 3 bytes have been displayed) then output a new line followed by &3F number of spaces
   (This positions the position on the new line to line up with the first byte (after address) of the previous
   line and reset X to #&FD (so that another 3 bytes can be output).
Load the next byte located at the Physical location [(&3A-&3B) + Y] and call routine &BD8F to output
  the 2-digit hex value of the byte (in A) followed by a space
Increment Y to point to the next byte
Decrement &38 (bytes to output)
If &38 is not 0 then jump back to &8954 to output the next byte value
[&896B] Now each hex byte of the assembled statement has been output (with 3 bytes output per line).
Set Y to X (i.e. the number of spare printable bytes (is byte is printed as 2 hex digits followed by a space) on the screen).
If Y is not &FF then we need to output some spaces, as not all 3 byte positions (B1, B2, B3) contained a value, so:
* [&896D] Increment Y
* If Y is not 0 then output 3 spaces and jump back to &896D
[&8977] Set X to #&0A (minimum length of label + 1 space).
Set A to the first byte of the Statement line (from BASIC Text pointer A (&0B,&0C)).
[Note: Y is initially zero].
If A is '.' then the label is output as follows:
* [&897F] Call routine &BD37 to output the character/token in A
* Decrement the length of the label field (X)
* If X is 0 then set X to 1 (as will must output 1 space after a label name)
* Increment Y (the current byte offset at the BASIC Text Pointer A address)
* Set A to the next byte from the BASIC Text Pointer A address (with the byte offset in Y)
* If Y is not equal &4E (the offset to the end of the label name in BASIC Text Pointer A, as stored by the assembly
    routine (&89EB)) then jump back to &897F to output the next character of the label name.
[&898E] Output X number of spaces (if a label was printed then X will be any used spaces in the 9-character label
field, or 1 if the label exceeded 8 characters in width; otherwise X will be 10).

Decrement Y (to point to the first character after the label name - which must be a space character).
[&8992] Skip any spaces after the label name by: incrementing Y until the character at the BASIC Text pointer A
location plus Y offset, is not the same as the character in A (which will be a space).

[&8997] Output the statement text as follows:
* Set A to the character at BASIC Text Pointer A plus offset (Y)
* If the character is ':' then:
# If Y is less that the BASIC Text Pointer A offset (location &0A), i.e. the position that routine &89EB
  stopped processing, then we are not at the end of the statement (i.e. the statement is a statement like
  'LDA#ASC(":")' which contains a ':' prior to the end of statement) then jump to &89A1 to output the
  character and then continue outputting the statement text.
# Otherwise, Output a new line (line break) and jump to &89AE to Check and skip the end of the statement/program
  line.
* If the character is '<cr>' then output a new line and jump to &89AE to check and skip the end of the program line
* [&89A1] call routine &BD37 to output the character
* Increment Y (BASIC Text Pointer A offset)
* Jump back to &8997 to output the next character of the statement text

[&89AE] Check and skip end of statement/program line
Set Y to the BASIC Text pointer A offset value (location &0A), i.e. the position that routine &89EB stopped
processing; and decrement Y (to point to the last character, which should either be ':' or '<cr>').

[&89B1] Load the next character at the BASIC Text pointer A location + the Y offset value.
If the character is not ':' or '<cr>' then jump back to &89B1 to check the nexct character. This will skip any
program comment that is located between the end of the Assembly statement and the end of statement marker (note that any
such comments [which do not have to be preceeded by a '\' character!] will still be output in the assembly listing, but
they will not be processed - as all characters are skipped until a ':' or '<cr>' character is found).
This means that problems could occur in such cases as follows:
     'CMP#ASC("9") \ Was ASC(":")'
which will not work, as BASIC will assume that the ':' is an end of statement marker and start processing '")' as the next
assembly statement - resulting in a 'Syntax error'.

Call routine &9BA8 to check for the end of statement (and add Y to the BASIC Text Pointer A address).
If the character pointed to by BASIC text pointer A (i.e. the last character of the statement) is ':' then jump to
&8920 to assemble the next statement on the program line.

Otherwise, the character is '<cr>', so check the BASIC Text pointer A MSB address (&0C). If the MSB address
of the statement text is &07, then we are not currently executing a program, instead we are executing a command line
command, so jump to &8F86 to return to the command line prompt.
Otherwise, we are executing a program, so call routine &9BDE to Check the next program line, returning to the command
line prompt if no more lines were found, and to skip and display (if TRACE is on) the Line Number.
Jump back to &8920 to assemble the statement on this new program line, or to exit if a ']' character is found.


Disassembly for the '[' Begin Assembly routine

891A : 058 3A DEC A
891B ( 133 040 85 28 STA &28
891D L 076 011 144 4C 0B 90 JMP &900B Process next BASIC program statement
8920   032 224 142 20 E0 8E JSR &8EE0 Get next non-space character pointed to by Ptr A
8923 I] 073 093 49 5D EOR#&5D
8925   240 243 F0 F3 BEQ -13 --> &891A
8927   032 188 155 20 BC 9B JSR &9BBC Add Y to Text pointer A & then reset offset to 1) & check for Escape condition
892A   198 010 C6 0A DEC &0A
892C   032 235 137 20 EB 89 JSR &89EB Assemble Assembly instruction/statement
892F   198 010 C6 0A DEC &0A
8931 ( 165 040 A5 28 LDA &28
8933 J 074 4A LSR A
8934 x 144 120 90 78 BCC 120 --> &89AE
8936   165 030 A5 1E LDA &1E
8938 i 105 004 69 04 ADC#&04
893A ? 133 063 85 3F STA &3F
893C 8 165 056 A5 38 LDA &38
893E l 032 108 189 20 6C BD JSR &BD6C Output the 2-digit Hexadecimal number stored in A
8941 7 165 055 A5 37 LDA &37
8943   032 143 189 20 8F BD JSR &BD8F Output the 2-digit Hexadecimal number stored in A followed by a space
8946   162 252 A2 FC LDX#&FC
8948 9 164 057 A4 39 LDY &39
894A   016 002 10 02 BPL 2 --> &894E
894C 6 164 054 A4 36 LDY &36
894E 8 132 056 84 38 STY &38
8950   240 025 F0 19 BEQ 25 --> &896B
8952   160 000 A0 00 LDY#&00
8954   232 E8 INX
8955   208 010 D0 0A BNE 10 --> &8961
8957   032 146 186 20 92 BA JSR &BA92 Output a new line
895A ? 166 063 A6 3F LDX &3F
895C   032 191 189 20 BF BD JSR &BDBF Output X number of Spaces
895F   162 253 A2 FD LDX#&FD
8961 : 177 058 B1 3A LDA (&3A),Y
8963   032 143 189 20 8F BD JSR &BD8F Output the 2-digit Hexadecimal number stored in A followed by a space
8966   200 C8 INY
8967 8 198 056 C6 38 DEC &38
8969   208 233 D0 E9 BNE -23 --> &8954
896B   138 8A TXA
896C   168 A8 TAY
896D   200 C8 INY
896E   240 007 F0 07 BEQ 7 --> &8977
8970   162 003 A2 03 LDX#&03
8972   032 191 189 20 BF BD JSR &BDBF Output X number of Spaces
8975   128 246 80 F6 BRA -10 --> &896D
8977   162 010 A2 0A LDX#&0A
8979   178 011 B2 0B LDA (&0B)
897B . 201 046 C9 2E CMP#&2E
897D   208 015 D0 0F BNE 15 --> &898E
897F 7 032 055 189 20 37 BD JSR &BD37 Output Character/Token on screen
8982   202 CA DEX
8983   208 002 D0 02 BNE 2 --> &8987
8985   162 001 A2 01 LDX#&01
8987   200 C8 INY
8988   177 011 B1 0B LDA (&0B),Y
898A N 196 078 C4 4E CPY &4E
898C   208 241 D0 F1 BNE -15 --> &897F
898E   032 191 189 20 BF BD JSR &BDBF Output X number of Spaces
8991   136 88 DEY
8992   200 C8 INY
8993   209 011 D1 0B CMP (&0B),Y
8995   240 251 F0 FB BEQ -5 --> &8992
8997   177 011 B1 0B LDA (&0B),Y
8999 : 201 058 C9 3A CMP#&3A
899B   240 010 F0 0A BEQ 10 --> &89A7
899D   201 013 C9 0D CMP#&0D
899F   240 010 F0 0A BEQ 10 --> &89AB
89A1 7 032 055 189 20 37 BD JSR &BD37 Output Character/Token on screen
89A4   200 C8 INY
89A5   128 240 80 F0 BRA -16 --> &8997
89A7   196 010 C4 0A CPY &0A
89A9   144 246 90 F6 BCC -10 --> &89A1
89AB   032 146 186 20 92 BA JSR &BA92 Output a new line
89AE   164 010 A4 0A LDY &0A
89B0   136 88 DEY
89B1   200 C8 INY
89B2   177 011 B1 0B LDA (&0B),Y
89B4 : 201 058 C9 3A CMP#&3A
89B6   240 004 F0 04 BEQ 4 --> &89BC
89B8   201 013 C9 0D CMP#&0D
89BA   208 245 D0 F5 BNE -11 --> &89B1
89BC   032 168 155 20 A8 9B JSR &9BA8 Check end of Statement
89BF   178 011 B2 0B LDA (&0B)
89C1 : 201 058 C9 3A CMP#&3A
89C3   240 012 F0 0C BEQ 12 --> &89D1
89C5   165 012 A5 0C LDA &0C
89C7   201 007 C9 07 CMP#&07
89C9   208 003 D0 03 BNE 3 --> &89CE
89CB L 076 134 143 4C 86 8F JMP &8F86 Read & execute command line input
89CE   032 222 155 20 DE 9B JSR &9BDE Skip Program Line Number
89D1 L 076 032 137 4C 20 89 JMP &8920 Assemble next assembly statement

 


 Back to 8BS
Or