You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1010 lines
12 KiB

TITLE BBC BASIC (C) R.T.RUSSELL 1981-2024
NAME ('ASMB')
;
;BBC BASIC INTERPRETER - Z80 VERSION
;Z80 CPU ASSEMBLER MODULE - "ASMB"
;(C) COPYRIGHT R.T.RUSSELL 1981-2024
;
;THE NAME BBC BASIC IS USED WITH THE PERMISSION
;OF THE BRITISH BROADCASTING CORPORATION AND IS
;NOT TRANSFERRABLE TO A FORKED OR DERIVED WORK.
;
;VERSION 5.0, 14-05-2024
;
GLOBAL ASSEM
;
EXTRN TABIT
EXTRN CRLF
EXTRN OUT
EXTRN VAR
EXTRN ZERO
EXTRN STOREN
EXTRN ERROR
EXTRN EXPRI
EXTRN EXPRS
;
EXTRN LISTON
EXTRN COUNT
EXTRN ACCS
EXTRN OC
EXTRN PC
;
CR EQU 0DH
TAND EQU 80H
TOR EQU 84H
TERROR EQU 85H
TCALL EQU 0D6H
TDEF EQU 0DDH
;
;ASSEMBLER:
;LANGUAGE-INDEPENDENT CONTROL SECTION:
; Outputs: A=delimiter, carry set if syntax error.
;
ASSEM: CALL SKIP
INC IY
CP ':'
JR Z,ASSEM
CP ']'
RET Z
CP CR
RET Z
DEC IY
LD IX,(PC) ;PROGRAM COUNTER
LD HL,LISTON
BIT 6,(HL)
JR Z,ASSEM0
LD IX,(OC) ;ORIGIN of CODE
ASSEM0: PUSH IX
PUSH IY
CALL ASMB
POP BC
POP DE
RET C
CALL SKIP
SCF
RET NZ
DEC IY
ASSEM3: INC IY
LD A,(IY)
CALL TERM0
JR NZ,ASSEM3
LD A,(LISTON)
PUSH IX
POP HL
OR A
SBC HL,DE
EX DE,HL ;DE= NO. OF BYTES
PUSH HL
LD HL,(PC)
PUSH HL
ADD HL,DE
LD (PC),HL ;UPDATE PC
BIT 6,A
JR Z,ASSEM5
LD HL,(OC)
ADD HL,DE
LD (OC),HL ;UPDATE OC
ASSEM5: POP HL ;OLD PC
POP IX ;CODE HERE
BIT 4,A
JR Z,ASSEM
LD A,H
CALL HEX
LD A,L
CALL HEXSP
XOR A
CP E
JR Z,ASSEM2
ASSEM1: LD A,(COUNT)
CP 17
LD A,5
CALL NC,TABIT ;NEXT LINE
LD A,(IX)
CALL HEXSP
INC IX
DEC E
JR NZ,ASSEM1
ASSEM2: LD A,18
CALL TABIT
PUSH IY
POP HL
SBC HL,BC
ASSEM4: LD A,(BC)
CALL OUT
INC BC
DEC L
JR NZ,ASSEM4
CALL CRLF
JP ASSEM
;
HEXSP: CALL HEX
LD A,' '
JR OUTCH1
HEX: PUSH AF
RRCA
RRCA
RRCA
RRCA
CALL HEXOUT
POP AF
HEXOUT: AND 0FH
ADD A,90H
DAA
ADC A,40H
DAA
OUTCH1: JP OUT
;
;PROCESSOR-SPECIFIC TRANSLATION SECTION:
;
;REGISTER USAGE: B - TYPE OF MOST RECENT OPERAND
; C - OPCODE BEING BUILT
; D - (IX) OR (IY) FLAG
; E - OFFSET FROM IX OR IY
; HL - NUMERIC OPERAND VALUE
; IX - CODE DESTINATION
; IY - SOURCE TEXT POINTER
; Inputs: A = initial character
; Outputs: Carry set if syntax error.
;
ASMB: CP '.'
JR NZ,ASMB1
INC IY
PUSH IX
CALL VAR
PUSH AF
CALL ZERO
EXX
LD HL,(PC)
EXX
LD A,(LISTON)
AND 20H
JR NZ,ASMB0
LD A,(IX)
OR (IX+1)
LD A,3
JP NZ,ERROR ;Multiple label
ASMB0: POP AF
CALL STOREN
POP IX
ASMB1: CALL SKIP
RET Z
CP TCALL
LD C,0C4H
INC IY
JP Z,GRPC
DEC IY
LD HL,OPCODS
CALL FIND
RET C
LD C,B ;ROOT OPCODE
LD D,0 ;CLEAR IX/IY FLAG
;
;GROUP 0 - TRIVIAL CASES REQUIRING NO COMPUTATION
;GROUP 1 - AS GROUP 0 BUT WITH "ED" PREFIX
;
SUB 39
JR NC,GROUP2
CP 15-39
CALL NC,ED
JR BYTE0
;
;GROUP 2 - BIT, RES, SET
;GROUP 3 - RLC, RRC, RL, RR, SLA, SRA, SRL
;
GROUP2: SUB 10
JR NC,GROUP4
CP 3-10
CALL C,BIT
RET C
CALL REGLO
RET C
CALL CB
JR BYTE0
;
;GROUP 4 - PUSH, POP, EX (SP)
;
GROUP4: SUB 3
JR NC,GROUP5
G4: CALL PAIR
RET C
JR BYTE0
;
;GROUP 5 - SUB, AND, XOR, OR, CP
;GROUP 6 - ADD, ADC, SBC
;
GROUP5: SUB 8+2
JR NC,GROUP7
CP 5-8
LD B,7
CALL NC,OPND
LD A,B
CP 7
JR NZ,G6HL
G6: CALL REGLO
LD A,C
JR NC,BIND1
XOR 46H
CALL BIND
DB: CALL NUMBER
JR VAL8
;
G6HL: AND 3FH
CP 12
SCF
RET NZ
LD A,C
CP 80H
LD C,9
JR Z,G4
XOR 1CH
RRCA
LD C,A
CALL ED
JR G4
;
;GROUP 7 - INC, DEC
;
GROUP7: SUB 2
JR NC,GROUP8
CALL REGHI
LD A,C
BIND1: JP NC,BIND
XOR 64H
RLCA
RLCA
RLCA
LD C,A
CALL PAIR1
RET C
BYTE0: LD A,C
JR BYTE2
;
;GROUP 8 - IN
;GROUP 9 - OUT
;
GROUP8: SUB 2
JR NC,GROUPA
CP 1-2
CALL Z,CORN
EX AF,AF'
CALL REGHI
RET C
EX AF,AF'
CALL C,CORN
INC H
JR Z,BYTE0
LD A,B
CP 7
SCF
RET NZ
LD A,C
XOR 3
RLCA
RLCA
RLCA
CALL BYTE
JR VAL8
;
;GROUP 10 - JR, DJNZ
;
GROUPA: SUB 2
JR NC,GROUPB
CP 1-2
CALL NZ,COND
LD A,C
JR NC,GRPA
LD A,18H
GRPA: CALL BYTE
CALL NUMBER
LD DE,(PC)
INC DE
SCF
SBC HL,DE
LD A,L
RLA
SBC A,A
CP H
TOOFAR: LD A,1
JP NZ,ERROR ;"Out of range"
VAL8: LD A,L
JR BYTE2
;
;GROUP 11 - JP
;
GROUPB: LD B,A
JR NZ,GROUPC
CALL COND
LD A,C
JR NC,GRPB
LD A,B
AND 3FH
CP 6
LD A,0E9H
JR Z,BYTE2
LD A,0C3H
GRPB: CALL BYTE
JR ADDR
;
;GROUP 12 - CALL
;
GROUPC: DJNZ GROUPD
GRPC: CALL GRPE
ADDR: CALL NUMBER
VAL16: CALL VAL8
LD A,H
JR BYTE2
;
;GROUP 13 - RST
;
GROUPD: DJNZ GROUPE
CALL NUMBER
AND C
OR H
JR NZ,TOOFAR
LD A,L
OR C
BYTE2: JR BYTE1
;
;GROUP 14 - RET
;
GROUPE: DJNZ GROUPF
GRPE: CALL COND
LD A,C
JR NC,BYTE1
OR 9
JR BYTE1
;
;GROUP 15 - LD
;
GROUPF: DJNZ MISC
CALL LDOP
JR NC,LDA
CALL REGHI
EX AF,AF'
CALL SKIP
CP '('
JR Z,LDIN
EX AF,AF'
JP NC,G6
LD C,1
CALL PAIR1
RET C
LD A,14
CP B
LD B,A
CALL Z,PAIR
LD A,B
AND 3FH
CP 12
LD A,C
JR NZ,GRPB
LD A,0F9H
JR BYTE1
;
LDIN: EX AF,AF'
PUSH BC
CALL NC,REGLO
LD A,C
POP BC
JR NC,BIND
LD C,0AH
CALL PAIR1
CALL LD16
JR NC,GRPB
CALL NUMBER
LD C,2
CALL PAIR
CALL LD16
RET C
CALL BYTE
JR VAL16
;
;OPT - SET OPTION
;
OPT: DEC B
JP Z,DB
DJNZ ADDR
CALL NUMBER
LD HL,LISTON
LD C,A
RLD
LD A,C
RRD
RET
;
LDA: CP 4
CALL C,ED
LD A,B
BYTE1: JR BYTE
;
;MISC - DEFB, DEFW, DEFM
;
MISC: DJNZ OPT
PUSH IX
CALL EXPRS
POP IX
LD HL,ACCS
DEFM1: XOR A
CP E
RET Z
LD A,(HL)
INC HL
CALL BYTE
DEC E
JR DEFM1
;
;SUBROUTINES:
;
LD16: LD A,B
JR C,LD8
LD A,B
AND 3FH
CP 12
LD A,C
RET Z
CALL ED
LD A,C
OR 43H
RET
;
LD8: CP 7
SCF
RET NZ
LD A,C
OR 30H
RET
;
CORN: PUSH BC
CALL OPND
BIT 5,B
POP BC
JR Z,NUMBER
LD H,-1
ED: LD A,0EDH
JR BYTE
;
CB: LD A,0CBH
BIND: CP 76H
SCF
RET Z ;REJECT LD (HL),(HL)
CALL BYTE
INC D
RET P
LD A,E
JR BYTE
;
OPND: PUSH HL
LD HL,OPRNDS
CALL FIND
POP HL
RET C
BIT 7,B
RET Z
BIT 3,B
PUSH HL
CALL Z,OFFSET
LD E,L
POP HL
LD A,0DDH
BIT 6,B
JR Z,OP1
LD A,0FDH
OP1: OR A
INC D
LD D,A
RET M
BYTE: LD (IX),A
INC IX
OR A
RET
;
OFFSET: LD A,(IY)
CP ')'
LD HL,0
RET Z
NUMBER: CALL SKIP
PUSH BC
PUSH DE
PUSH IX
CALL EXPRI
POP IX
EXX
POP DE
POP BC
LD A,L
OR A
RET
;
REG: CALL OPND
RET C
LD A,B
AND 3FH
CP 8
CCF
RET
;
REGLO: CALL REG
RET C
JR ORC
;
REGHI: CALL REG
RET C
JR SHL3
;
COND: CALL OPND
RET C
LD A,B
AND 1FH
SUB 16
JR NC,SHL3
CP -15
SCF
RET NZ
LD A,3
JR SHL3
;
PAIR: CALL OPND
RET C
PAIR1: LD A,B
AND 0FH
SUB 8
RET C
JR SHL3
;
BIT: CALL NUMBER
CP 8
CCF
RET C
SHL3: RLCA
RLCA
RLCA
ORC: OR C
LD C,A
RET
;
LDOP: LD HL,LDOPS
FIND: CALL SKIP
EXIT: LD B,0
SCF
RET Z
CP TDEF
JR Z,FIND0
CP TOR+1
CCF
RET C
FIND0: LD A,(HL)
OR A
JR Z,EXIT
XOR (IY)
AND 01011111B
JR Z,FIND2
FIND1: BIT 7,(HL)
INC HL
JR Z,FIND1
INC HL
INC B
JR FIND0
;
FIND2: PUSH IY
FIND3: BIT 7,(HL)
INC IY
INC HL
JR NZ,FIND5
CP (HL)
CALL Z,SKIP0
LD A,(HL)
XOR (IY)
AND 01011111B
JR Z,FIND3
FIND4: POP IY
JR FIND1
;
FIND5: CALL DELIM
CALL NZ,SIGN
JR NZ,FIND4
FIND6: LD A,B
LD B,(HL)
POP HL
RET
;
SKIP0: INC HL
SKIP: CALL DELIM
RET NZ
CALL TERM
RET Z
INC IY
JR SKIP
;
SIGN: CP '+'
RET Z
CP '-'
RET
;
DELIM: LD A,(IY) ;ASSEMBLER DELIMITER
CP ' '
RET Z
CP ','
RET Z
CP ')'
RET Z
TERM: CP ';' ;ASSEMBLER TERMINATOR
RET Z
CP '\'
RET Z
TERM0: CP ':' ;ASSEMBLER SEPARATOR
RET NC
CP CR
RET
;
OPCODS: DEFM 'NO'
DEFB 'P'+80H
DEFB 0
DEFM 'RLC'
DEFB 'A'+80H
DEFB 7
DEFM 'EX'
DEFB 0
DEFM 'AF'
DEFB 0
DEFM 'AF'
DEFB ''''+80H
DEFB 8
DEFM 'RRC'
DEFB 'A'+80H
DEFB 0FH
DEFM 'RL'
DEFB 'A'+80H
DEFB 17H
DEFM 'RR'
DEFB 'A'+80H
DEFB 1FH
DEFM 'DA'
DEFB 'A'+80H
DEFB 27H
DEFM 'CP'
DEFB 'L'+80H
DEFB 2FH
DEFM 'SC'
DEFB 'F'+80H
DEFB 37H
DEFM 'CC'
DEFB 'F'+80H
DEFB 3FH
DEFM 'HAL'
DEFB 'T'+80H
DEFB 76H
DEFM 'EX'
DEFB 'X'+80H
DEFB 0D9H
DEFM 'EX'
DEFB 0
DEFM 'DE'
DEFB 0
DEFM 'H'
DEFB 'L'+80H
DEFB 0EBH
DEFM 'D'
DEFB 'I'+80H
DEFB 0F3H
DEFM 'E'
DEFB 'I'+80H
DEFB 0FBH
;
DEFM 'NE'
DEFB 'G'+80H
DEFB 44H
DEFM 'IM'
DEFB 0
DEFB '0'+80H
DEFB 46H
DEFM 'RET'
DEFB 'N'+80H
DEFB 45H
DEFM 'RET'
DEFB 'I'+80H
DEFB 4DH
DEFM 'IM'
DEFB 0
DEFB '1'+80H
DEFB 56H
DEFM 'IM'
DEFB 0
DEFB '2'+80H
DEFB 5EH
DEFM 'RR'
DEFB 'D'+80H
DEFB 67H
DEFM 'RL'
DEFB 'D'+80H
DEFB 6FH
DEFM 'LD'
DEFB 'I'+80H
DEFB 0A0H
DEFM 'CP'
DEFB 'I'+80H
DEFB 0A1H
DEFM 'IN'
DEFB 'I'+80H
DEFB 0A2H
DEFM 'OUT'
DEFB 'I'+80H
DEFB 0A3H
DEFM 'LD'
DEFB 'D'+80H
DEFB 0A8H
DEFM 'CP'
DEFB 'D'+80H
DEFB 0A9H
DEFM 'IN'
DEFB 'D'+80H
DEFB 0AAH
DEFM 'OUT'
DEFB 'D'+80H
DEFB 0ABH
DEFM 'LDI'
DEFB 'R'+80H
DEFB 0B0H
DEFM 'CPI'
DEFB 'R'+80H
DEFB 0B1H
DEFM 'INI'
DEFB 'R'+80H
DEFB 0B2H
DEFM 'OTI'
DEFB 'R'+80H
DEFB 0B3H
DEFM 'LDD'
DEFB 'R'+80H
DEFB 0B8H
DEFM 'CPD'
DEFB 'R'+80H
DEFB 0B9H
DEFM 'IND'
DEFB 'R'+80H
DEFB 0BAH
DEFM 'OTD'
DEFB 'R'+80H
DEFB 0BBH
;
DEFM 'BI'
DEFB 'T'+80H
DEFB 40H
DEFM 'RE'
DEFB 'S'+80H
DEFB 80H
DEFM 'SE'
DEFB 'T'+80H
DEFB 0C0H
;
DEFM 'RL'
DEFB 'C'+80H
DEFB 0
DEFM 'RR'
DEFB 'C'+80H
DEFB 8
DEFM 'R'
DEFB 'L'+80H
DEFB 10H
DEFM 'R'
DEFB 'R'+80H
DEFB 18H
DEFM 'SL'
DEFB 'A'+80H
DEFB 20H
DEFM 'SR'
DEFB 'A'+80H
DEFB 28H
DEFM 'SR'
DEFB 'L'+80H
DEFB 38H
;
DEFM 'PO'
DEFB 'P'+80H
DEFB 0C1H
DEFM 'PUS'
DEFB 'H'+80H
DEFB 0C5H
DEFM 'EX'
DEFB 0
DEFM '(S'
DEFB 'P'+80H
DEFB 0E3H
;
DEFM 'SU'
DEFB 'B'+80H
DEFB 90H
DEFM 'AN'
DEFB 'D'+80H
DEFB 0A0H
DEFM 'XO'
DEFB 'R'+80H
DEFB 0A8H
DEFM 'O'
DEFB 'R'+80H
DEFB 0B0H
DEFM 'C'
DEFB 'P'+80H
DEFB 0B8H
DEFB TAND
DEFB 0A0H
DEFB TOR
DEFB 0B0H
;
DEFM 'AD'
DEFB 'D'+80H
DEFB 80H
DEFM 'AD'
DEFB 'C'+80H
DEFB 88H
DEFM 'SB'
DEFB 'C'+80H
DEFB 98H
;
DEFM 'IN'
DEFB 'C'+80H
DEFB 4
DEFM 'DE'
DEFB 'C'+80H
DEFB 5
;
DEFM 'I'
DEFB 'N'+80H
DEFB 40H
DEFM 'OU'
DEFB 'T'+80H
DEFB 41H
;
DEFM 'J'
DEFB 'R'+80H
DEFB 20H
DEFM 'DJN'
DEFB 'Z'+80H
DEFB 10H
;
DEFM 'J'
DEFB 'P'+80H
DEFB 0C2H
;
DEFM 'CAL'
DEFB 'L'+80H
DEFB 0C4H
;
DEFM 'RS'
DEFB 'T'+80H
DEFB 0C7H
;
DEFM 'RE'
DEFB 'T'+80H
DEFB 0C0H
;
DEFM 'L'
DEFB 'D'+80H
DEFB 40H
;
DEFB TDEF AND 7FH
DEFB 'M'+80H
DEFB 0
;
DEFB TDEF AND 7FH
DEFB 'B'+80H
DEFB 0
;
DEFM 'OP'
DEFB 'T'+80H
DEFB 0
;
DEFB TDEF AND 7FH
DEFB 'W'+80H
DEFB 0
;
DEFB 0
;
OPRNDS: DEFB 'B'+80H
DEFB 0
DEFB 'C'+80H
DEFB 1
DEFB 'D'+80H
DEFB 2
DEFB 'E'+80H
DEFB 3
DEFB 'H'+80H
DEFB 4
DEFB 'L'+80H
DEFB 5
DEFM '(H'
DEFB 'L'+80H
DEFB 6
DEFB 'A'+80H
DEFB 7
DEFM '(I'
DEFB 'X'+80H
DEFB 86H
DEFM '(I'
DEFB 'Y'+80H
DEFB 0C6H
;
DEFM 'B'
DEFB 'C'+80H
DEFB 8
DEFM 'D'
DEFB 'E'+80H
DEFB 10
DEFM 'H'
DEFB 'L'+80H
DEFB 12
DEFM 'I'
DEFB 'X'+80H
DEFB 8CH
DEFM 'I'
DEFB 'Y'+80H
DEFB 0CCH
DEFM 'A'
DEFB 'F'+80H
DEFB 14
DEFM 'S'
DEFB 'P'+80H
DEFB 14
;
DEFM 'N'
DEFB 'Z'+80H
DEFB 16
DEFB 'Z'+80H
DEFB 17
DEFM 'N'
DEFB 'C'+80H
DEFB 18
DEFM 'P'
DEFB 'O'+80H
DEFB 20
DEFM 'P'
DEFB 'E'+80H
DEFB 21
DEFB 'P'+80H
DEFB 22
DEFB 'M'+80H
DEFB 23
;
DEFM '('
DEFB 'C'+80H
DEFB 20H
;
DEFB 0
;
LDOPS: DEFM 'I'
DEFB 0
DEFB 'A'+80H
DEFB 47H
DEFM 'R'
DEFB 0
DEFB 'A'+80H
DEFB 4FH
DEFM 'A'
DEFB 0
DEFB 'I'+80H
DEFB 57H
DEFM 'A'
DEFB 0
DEFB 'R'+80H
DEFB 5FH
DEFM '(BC'
DEFB 0
DEFB 'A'+80H
DEFB 2
DEFM '(DE'
DEFB 0
DEFB 'A'+80H
DEFB 12H
DEFM 'A'
DEFB 0
DEFM '(B'
DEFB 'C'+80H
DEFB 0AH
DEFM 'A'
DEFB 0
DEFM '(D'
DEFB 'E'+80H
DEFB 1AH
;
DEFB 0
;
FIN: END