8-Bit Software

The BBC and Master Computer Public Domain Library

Back to 8BS Or Back to Disassembly


BASIC IV ROM Routines
Page Last Altered:


802C BASIC ROM service startup

Submitted by Steve Fewell

Description:

Firstly, A & Y are pushed to the 6502 stack (to save their value)
Then the value in A is checked and the following operations are carried out depending
on its value (listed are the service type numbers, the definition of the service number
and the execution address for the service call):
&09 - *HELP instruction expansion (issued by MOS when user enters *HELP instruction) --> &804C
&04 - Unrecognised command (issued by MOS for unrecognised *-command) --> &8070
&02 - Relative Private workspace claim (issued by MOS after a [BREAK]) --> &8040
&27 - A Reset has occurred (issed by MOS on hard reset) --> &8040 (same as &02, above)

If A contains none of the above values then [&806A] Y & A are pulled from the 6502 stack
and X is set to the RAM copy of the currently selected paged ROM (from zero page memory location &F4),
which is the ROM number of this BASIC ROM. Then the service call is exited (RTS).

Following are descriptions of these 3 service call routines


&8040 Write the BASIC ROM number
This routine services service calls &02 (issued after a [BREAK]) and &27 (issued after a hard reset - power-on
or [CTRL]+[BREAK]).

OSBYTE call &BB is issued to write the BASIC ROM number. It is called with:
    X = contents of zero page location (&F4) - i.e. the currently selected ROM
    Y = #&00 - the command for Writing the BASIC ROM number value.
So the MOS is told that the BASIC ROM number is that of the currently active ROM.

Next [&806A] is called to pull Y and A from the 6502 stack and to set X to the RAM copy of the currently
selected paged ROM (from zero page memory location &F4 - which should be the ROM number for this BASIC ROM)
and then exit the service call (RTS).


&804C
This routine services service call &09 which is issued during a *HELP command.

The next byte pointed to by the address in locations &F2-&F3 plus the offset in Y register is read.
This byte is the first byte after the '*HELP' part of the issued command.

If this byte is not a carriage-return (ASCII 13) then BASIC ignores the *HELP command as BASIC does
not provide help on any keywords, so [&806A] is called to pull Y and A from the 6502 stack and to set X to the
currently selected paged ROM (from zero page memory location &F4 - which should be the ROM number for this
BASIC ROM) and then exit the service call (RTS).

Otherwise, the *HELP command did not contain any keywords (parameters), so BASIC will just list its name and
version number as follows:
  * Call OSNEWL (&FFE7) to start a new output line on the display.
  * Read the BASIC ROM Name and Version number from location &8009 [&7F13 + &F6] to &8012 [&7F13 + &FF].
    This is the text: "BASIC" + ASCII 0 + "4r32". Each character is output using the OSASCI (&FFE3) routine,
    except that the ASCII 0 character is replaced by a space.

OSNEWL (&FFE7) is called again to start a new output line.
Next [&8067] &80D8 is called to clear Bit 6 of memory location &F4 (the RAM copy of the current paged ROM).
Lastly, [&806A] pull Y and A from the 6502 stack, set X to the currently selected paged ROM (from zero page
memory location &F4 - which should be the ROM number for this BASIC ROM) and then exit the service call (RTS).


&8070
This routine services service call &04 which is issued when an unrecognised *-command is entered.

The first letter of the unrecognised command (pointed to by the address at &F2-&F3 + the offset in the Y register)
is read. This letter is ANDed with #&DF (1101 1111) to convert the letter to uppercase (if it was lowercase).
If this letter is "H" (the first letter of HIBASIC) then:
     * Bit 6 of the RAM copy of the current paged ROM (address &F4) is set.
     * Read the next letter of the unrecognised command.
     * If the letter is "." then jump to &80A8.
     * If the letter (once converted to uppercase -> AND#&DF) is "I" then jump to &808F.
     * Otherwise if not "." or "I", then the command is not "HIBASIC", so:
         - Call [&80D8] to clear Bit 6 of memory location &F4 (the RAM copy of the current paged ROM).
         - Decrement Y by 2 (so it points again to the first letter of the unrecognised command).
         - Call [&80D8] to clear Bit 6 of memory location &F4 (the RAM copy of the current paged ROM).

[&808F] This location is reached both if the letters "HI" are found, or if they were not found (and Y points again
at the start of the unrecognised command). The difference is that if "HI" was found that bit 6 of location &F4 will
be set. As I guess the MOS doesn't use this bit of the location, BASIC uses it to determine wither HIBASIC (via TUBE)
is active or standard BASIC (without TUBE relocation).

Next, the unrecognised command (starting at location Y) will be checked against the string "BASIC". The ROM name in
the ROM header (locations &8009 [&7F0E + &FB] to &800D [&7F0E + &FF]) is used to compare against the unrecognised
command (after converting the unrecognised command letter to uppercase -> AND#&DF).
If a "." is found then a match is assumed and address &80A8 is jumped to.

If any letter fails to match against the corresponding letter of the ROM name "BASIC", then the unrecognised
command is unrecognised by BASIC (i.e. it is not "HIBASIC" or "BASIC"), so:
[&8067] &80D8 is called to clear Bit 6 of memory location &F4 (the RAM copy of the current paged ROM).
then: pull Y and A from the 6502 stack, set X to the currently selected paged ROM (from zero page memory location
&F4 - which should be the ROM number for this BASIC ROM) and then exit the service call (RTS).

If the unrecognised command matches against "BASIC", then the next byte of the unrecognised command is checked.
If this byte is greater than or equal to "!" [ASCII 33] then the unrecognised command doesn't match "HIBASIC" or
"BASIC", as it doesn't terminate with a space or a carriage return [ASCII 13] after the "BASIC" string, so the
service call returns without a match as follows:
[&8067] &80D8 is called to clear Bit 6 of memory location &F4 (the RAM copy of the current paged ROM).
then: pull Y and A from the 6502 stack, set X to the currently selected paged ROM (from zero page memory location
&F4 - which should be the ROM number for this BASIC ROM) and then exit the service call (RTS).

[&80A8] A match is found - the unrecognised command is either "HIBASIC" or "BASIC"
Bit 6 (the bit corresponding to the overflow flag) of location &F4 is checked to determin whether the "HIBASIC"
or "BASIC" command was issued.
If Bit 6 is clear then BASIC will be started as follows:
       * [&80CC] Place the ROM number from location &F4 into X (after disregarding bit 6 -> EOR#&40)
       * Jump to OSBYTE &8E (*FX 142) to enter the BASIC language ROM (the ROM Number in X).
       * Exit the service call (via the jump statement above).

Otherwise, Bit 6 is set and the "HIBASIC" command was issued.
So:
Call &BF66 to detect if the Tube is present.
If Tube is present then jump to &80CC to:
       * [&80CC] Place the ROM number from location &F4 into X (after disregarding bit 6 -> EOR#&40)
       * Jump to OSBYTE &8E (*FX 142) to enter the BASIC language ROM (the ROM Number in X).
          (Note: OSBYTE &8E automatically handles the relocation of the ROM Code to the High &B800 address).
       * Exit the service call (via the jump statement above).

Otherwise, Tube is not present so:
[&80B1] &80D8 is called to clear Bit 6 of memory location &F4 (the RAM copy of the current paged ROM).
Copy the following error BRK statement from locations &80C2-&80CB to locations &0100-&010A:
       BRK
       EQUB 0
       EQUS "No TUBE"
       BRK
Then jump to the code at &0100 to cause the MOS to display the Error "No TUBE".
Note: I'm not sure why BASIC needs to copy the error code instead of just executing it straight from the ROM!


Changes from BASIC IV:
The addition of a service address is completely new functionality that is not present in BASIC IV.
Additionally, BASIC IV did not have a TUBE version (e.g. HIBASIC) that specifically ran accross the TUBE.


Disassembly for the BASIC ROM service Startup routine

802C

H

72

48

PHA

802D

 

170

AA

TAX

802E

 

152

98

TYA

802F

H

72

48

PHA

8030

 

224 009

E0 09

CPX#&09

8032

 

240 024

F0 18

BEQ 24 --> &804C   

8034

 

224 004

E0 04

CPX#&04

8036

8

240 056

F0 38

BEQ 56 --> &8070   

8038

 

224 002

E0 02

CPX#&02

803A

 

240 004

F0 04

BEQ 4 --> &8040   

803C

'

224 039

E0 27

CPX#&27

803E

*

208 042

D0 2A

BNE 42 --> &806A   

8040

 

169 187

A9 BB

LDA#&BB

8042

 

166 244

A6 F4

LDX &F4

8044

 

160 000

A0 00

LDY#&00

8046

 

032 244 255

20 F4 FF

JSR &FFF4   OSBYTE

8049

Lj

076 106 128

4C 6A 80

JMP &806A   

804C

 

177 242

B1 F2

"LDA (&F2),Y"

804E

 

201 013

C9 0D

CMP#&0D

8050

 

208 024

D0 18

BNE 24 --> &806A   

8052

 

032 231 255

20 E7 FF

JSR &FFE7   OSNEWL

8055

 

162 246

A2 F6

LDX#&F6

8057

 

189 019 127

BD 13 7F

"LDA &7F13,X"

805A

 

208 002

D0 02

BNE 2 --> &805E

805C

 

169 032

A9 20

LDA#&20

805E

 

032 227 255

20 E3 FF

JSR &FFE3   OSASCI (Write Character)

8061

 

232

E8

INX

8062

 

208 243

D0 F3

BNE -13 --> &8057

8064

 

032 231 255

20 E7 FF

JSR &FFE7   OSNEWL

8067

 

032 216 128

20 D8 80

JSR &80D8   

806A

h

104

68

PLA

806B

 

168

A8

TAY

806C

 

166 244

A6 F4

LDX &F4

806E

h

104

68

PLA

806F

`

96

60

RTS

8070

 

177 242

B1 F2

"LDA (&F2),Y"

8072

)

041 223

29 DF

AND#&DF

8074

H

201 072

C9 48

CMP#&48

8076

 

208 023

D0 17

BNE 23 --> &808F

8078

 

200

C8

INY

8079

@

169 064

A9 40

LDA#&40

807B

 

004 244

04 F4

TSB &F4

807D

 

177 242

B1 F2

"LDA (&F2),Y"

807F

 

200

C8

INY

8080

.

201 046

C9 2E

CMP#&2E

8082

$

240 036

F0 24

BEQ 36 --> &80A8

8084

)

041 223

29 DF

AND#&DF

8086

I

201 073

C9 49

CMP#&49

8088

 

240 005

F0 05

BEQ 5 --> &808F

808A

 

032 216 128

20 D8 80

JSR &80D8   

808D

 

136

88

DEY

808E

 

136

88

DEY

808F

 

162 251

A2 FB

LDX#&FB

8091

 

177 242

B1 F2

"LDA (&F2),Y"

8093

.

201 046

C9 2E

CMP#&2E

8095

 

240 017

F0 11

BEQ 17 --> &80A8

8097

)

041 223

29 DF

AND#&DF

8099

 

221 014 127

DD 0E 7F

"CMP &7F0E,X"

809C

 

208 201

D0 C9

BNE -55 --> &8067

809E

 

200

C8

INY

809F

 

232

E8

INX

80A0

 

208 239

D0 EF

BNE -17 --> &8091

80A2

 

177 242

B1 F2

"LDA (&F2),Y"

80A4

!

201 033

C9 21

CMP#&21

80A6

 

176 191

B0 BF

BCS -65 --> &8067

80A8

$

036 244

24 F4

BIT &F4

80AA

P

080 032

50 20

BVC 32 --> &80CC

80AC

f

032 102 191

20 66 BF

JSR &BF66    Detect if Tube is present

80AF

 

208 027

D0 1B

BNE 27 --> &80CC

80B1

 

032 216 128

20 D8 80

JSR &80D8   

80B4

 

162 010

A2 0A

LDX#&0A

80B6

 

189 194 128

BD C2 80

"LDA &80C2,X"

80B9

 

157 000 001

9D 00 01

"STA &0100,X"

80BC

 

202

CA

DEX

80BD

 

016 247

10 F7

BPL -9 --> &80B6

80BF

L

076 000 001

4C 00 01

JMP &0100

80C2

 

0

0

BRK

80C3

 

0

0

BRK

80C4

No TUBE

078 111 032 084 085 066 069

4E 6F 20 54 55 42 45

EQUS "No TUBE"

80CB

E

000

00

BRK

80CC

 

165 244

A5 F4

LDA &F4

80CE

I@

073 064

49 40

EOR#&40

80D0

 

170

AA

TAX

80D1

 

169 142

A9 8E

LDA#&8E

80D3

 

160 000

A0 00

LDY#&00

80D5

L

076 244 255

4C F4 FF

JMP &FFF4   OSBYTE

80D8

@

169 064

A9 40

LDA#&40

80DA

 

020 244

14 F4

TRB &F4

80DC

`

96

60

RTS

 


 Back to 8BS
Or