Login

Subversion Repositories NedoOS

Rev

Rev 129 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

;##########################################################################
;# BSrom140 - Modified ZX Spectrum ROM - (c) Busy soft - Release 22.04.97 #
;##########################################################################
;                   Original ROM: (c) Amstrad



                OUTPUT  "bsrom140.bin"

VERZIA:         EQU     140

VERA:           EQU     VERZIA/100
VERB:           EQU     VERA*100
VERC:           EQU     VERZIA-VERB
VERD:           EQU     VERC/10
VERE:           EQU     VERD*10
VERF:           EQU     VERC-VERE

VER1:           EQU     '0'+VERA
VER2:           EQU     '0'+VERD
VER3:           EQU     '0'+VERF

                ORG     #0000

; RST #00
START:          DI
                XOR     A
                LD      DE,#FFFF
                JP      NMI_MENU                ; BSROM - jumps to NMI menu instead of START_NEW

; Error restart
; RST #08
ERROR_1:        LD      HL,(#5C5D)
                CALL    TOERR                   ; BSROM - cursor jumps to error
                JR      ERROR_2

; Print a character
; RST #10
PRINT_A:        JP      PRINT_A_2

; Unused bytes
                DW      #FFFF
                DW      #FFFF
                DB      #FF

; Collect a character
; RST #18
GET_CHAR:       LD      HL,(#5C5D)
                LD      A,(HL)
TEST_CHAR:      CALL    SKIP_OVER
                RET     NC
NEXT_CHAR:      CALL    CH_ADD_1
                JR      TEST_CHAR

; Unused bytes
                DW      #FFFF
                DB      #FF

; Calculator restart
; RST #28
                JP      CALCULATE

; Unused bytes
                DW      #FFFF
                DW      #FFFF
                DB      #FF

; Create free locations in work space
; RST #30
BC_SPACES:      PUSH    BC
                LD      HL,(#5C61)
                PUSH    HL
                JP      RESERVE

; Maskable interrupt routine
; RST #38
MASK_INT:       PUSH    AF
                PUSH    HL
                LD      HL,(#5C78)
                INC     HL
                LD      (#5C78),HL
                LD      A,H
                OR      L
                JR      NZ,KEY_INT
                INC     (IY+#40)
KEY_INT:        PUSH    BC
                PUSH    DE
                CALL    KEYBOARD
                POP     DE
                POP     BC
                POP     HL
                POP     AF
                EI
                RET

; A continuation of the code at #0008
ERROR_2:        POP     HL
                LD      L,(HL)
ERROR_3:        LD      (IY+#00),L
                LD      SP,(#5C3D)
                JP      SET_STK

; Unused bytes
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DB      #FF

; Non-maskable interrupt routine
; RST #66
RESET:          JP      NMI_MENU                ; BSROM - jumps to NMI menu

                DB      #B0                     ; Looks like this is unused torso
                DB      #5C                     ; of the original RESET routine.
                DB      #7C                     ;
                DB      #B5                     ;
                DB      #20, #01                ;
                DB      #E9                     ;
                DB      #E1                     ;
                DB      #F1                     ;
                DB      #ED, #45                ; End of unused bytes.

; Fetch the next immediate character following the current valid character address
; and update the associated system variable.
CH_ADD_1:       LD      HL,(#5C5D)
TEMP_PTR1:      INC     HL
TEMP_PTR2:      LD      (#5C5D),HL
                LD      A,(HL)
                RET

; Skip over white-space and other characters irrelevant to the parsing of a basic line
SKIP_OVER:      CP      #21
                RET     NC
                CP      #0D
                RET     Z
                CP      #10
                RET     C
                CP      #18
                CCF
                RET     C
                INC     HL
                CP      #16
                JR      C,SKIPS
                INC     HL
SKIPS:          SCF
                LD      (#5C5D),HL
                RET

; Six look-up tables for keyboard reading routine to decode the key values.
; Table for tokenized characters (134d-255d).
; Begins with function type words without a leading space.
; The last byte of a token is inverted to denote the end of the word.
TKN_TABLE:      DC      "?"                            
                DC      "RND"
                DC      "INKEY$"
                DC      "PI"
                DC      "FN"
                DC      "POINT"
                DC      "SCREEN$"
                DC      "ATTR"
                DC      "AT"
                DC      "TAB"
                DC      "VAL$"
                DC      "CODE"
                DC      "VAL"
                DC      "LEN"
                DC      "SIN"
                DC      "COS"
                DC      "TAN"
                DC      "ASN"
                DC      "ACS"
                DC      "ATN"
                DC      "LN"
                DC      "EXP"
                DC      "INT"
                DC      "SQR"
                DC      "SGN"
                DC      "ABS"
                DC      "PEEK"
                DC      "IN"
                DC      "USR"
                DC      "STR$"
                DC      "CHR$"
                DC      "NOT"
                DC      "BIN"
               
; Function type words with a leading space
; if they begin with a letter. 
                DC      "OR"                   
                DC      "AND"
                DC      "<="
                DC      ">="
                DC      "<>"
                DC      "LINE"
                DC      "THEN"
                DC      "TO"
                DC      "STEP"
                DC      "DEF FN"
                DC      "CAT"
                DC      "FORMAT"
                DC      "MOVE"
                DC      "ERASE"
                DC      "OPEN #"
                DC      "CLOSE #"
                DC      "MERGE"
                DC      "VERIFY"
                DC      "BEEP"
                DC      "CIRCLE"
                DC      "INK"
                DC      "PAPER"
                DC      "FLASH"
                DC      "BRIGHT"
                DC      "INVERSE"
                DC      "OVER"
                DC      "OUT"
                DC      "LPRINT"
                DC      "LLIST"
                DC      "STOP"
                DC      "READ"
                DC      "DATA"
                DC      "RESTORE"
                DC      "NEW"
                DC      "BORDER"
                DC      "CONTINUE"
                DC      "DIM"
                DC      "REM"
                DC      "FOR"
                DC      "GO TO"
                DC      "GO SUB"
                DC      "INPUT"
                DC      "LOAD"
                DC      "LIST"
                DC      "LET"
                DC      "PAUSE"
                DC      "NEXT"
                DC      "POKE"
                DC      "PRINT"
                DC      "PLOT"
                DC      "RUN"
                DC      "SAVE"
                DC      "RANDOMIZE"
                DC      "IF"
                DC      "CLS"
                DC      "DRAW"
                DC      "CLEAR"
                DC      "RETURN"
                DC      "COPY"

; maps for the standard 40-key ZX Spectrum keyboard
; SHIFT (#27) is read directly.
MAIN_KEYS:      DB      #42                     ;B
                DB      #48                     ;H
                DB      #59                     ;Y
                DB      #36                     ;6
                DB      #35                     ;5
                DB      #54                     ;T
                DB      #47                     ;G
                DB      #56                     ;V
                DB      #4E                     ;N
                DB      #4A                     ;J
                DB      #55                     ;U
                DB      #37                     ;7
                DB      #34                     ;4
                DB      #52                     ;R
                DB      #46                     ;F
                DB      #43                     ;C
                DB      #4D                     ;M
                DB      #4B                     ;K
                DB      #49                     ;I
                DB      #38                     ;8
                DB      #33                     ;3
                DB      #45                     ;E
                DB      #44                     ;D
                DB      #58                     ;X
                DB      #0E                     ;Symbol shift
                DB      #4C                     ;L
                DB      #4F                     ;O
                DB      #39                     ;9
                DB      #32                     ;2
                DB      #57                     ;W
                DB      #53                     ;S
                DB      #5A                     ;Z
                DB      #20                     ;Space
                DB      #0D                     ;Enter
                DB      #50                     ;P
                DB      #30                     ;0
                DB      #31                     ;1
                DB      #51                     ;Q
                DB      #41                     ;A

; Unshifted extended mode keys.
; The green keywords on the original keyboard.
E_UNSHIFT:      DB      #E3                     ;READ
                DB      #C4                     ;BIN
                DB      #E0                     ;LPRINT
                DB      #E4                     ;DATA
                DB      #B4                     ;TAN
                DB      #BC                     ;SGN
                DB      #BD                     ;ABS
                DB      #BB                     ;SQR
                DB      #AF                     ;CODE
                DB      #B0                     ;VAL
                DB      #B1                     ;LEN
                DB      #C0                     ;USR
                DB      #A7                     ;PI
                DB      #A6                     ;INKEY$
                DB      #BE                     ;PEEK
                DB      #AD                     ;TAB
                DB      #B2                     ;SIN
                DB      #BA                     ;INT
                DB      #E5                     ;RESTORE
                DB      #A5                     ;RND
                DB      #C2                     ;CHR$
                DB      #E1                     ;LLIST
                DB      #B3                     ;COS
                DB      #B9                     ;EXP
                DB      #C1                     ;STR$
                DB      #B8                     ;LN

; Shifted extended mode keys.
; The red keywords below keys on the original keyboard.
EXT_SHIFT:      DB      #7E                     ;~
                DB      #DC                     ;BRIGHT
                DB      #DA                     ;PAPER
                DB      #5C                     ;\
                DB      #B7                     ;ATN
                DB      #7B                     ;{
                DB      #7D                     ;}
                DB      #D8                     ;CIRCLE
                DB      #BF                     ;IN
                DB      #AE                     ;VAL$
                DB      #AA                     ;SCREEN$
                DB      #AB                     ;ATTR
                DB      #DD                     ;INVERSE
                DB      #DE                     ;OVER
                DB      #DF                     ;OUT
                DB      #7F                     ;(c)
                DB      #B5                     ;ASN
                DB      #D6                     ;VERIFY
                DB      #7C                     ;|
                DB      #D5                     ;MERGE
                DB      #5D                     ;]
                DB      #DB                     ;FLASH
                DB      #B6                     ;ACS
                DB      #D9                     ;INK
                DB      #5B                     ;[
                DB      #D7                     ;BEEP

; Shift key control codes assigned to the digits.
; White labels above the number characters on the digits keys on the orig. keyboard.
CTL_CODES:      DB      #0C                     ;DELETE
                DB      #07                     ;EDIT
                DB      #06                     ;Caps lock
                DB      #04                     ;True video
                DB      #05                     ;Inverse video
                DB      #08                     ;Cursor left
                DB      #0A                     ;Cursor down
                DB      #0B                     ;Cursor up
                DB      #09                     ;Cursor right
                DB      #0F                     ;GRAPH

; Keys shifted with Symbol shift.
; Red symbols on the alphabetic characters on the original keyboard.
SYM_CODES:      DB      #E2                     ;STOP
                DB      #2A                     ;*
                DB      #3F                     ;?
                DB      #CD                     ;STEP
                DB      #C8                     ;>=
                DB      #CC                     ;TO
                DB      #CB                     ;THEN
                DB      #5E                     ;^
                DB      #AC                     ;AT
                DB      #2D                     ;-
                DB      #2B                     ;+
                DB      #3D                     ;=
                DB      #2E                     ;.
                DB      #2C                     ;,
                DB      #3B                     ;;
                DB      #22                     ;"
                DB      #C7                     ;<=
                DB      #3C                     ;<
                DB      #C3                     ;NOT
                DB      #3E                     ;>
                DB      #C5                     ;OR
                DB      #2F                     ;/
                DB      #C9                     ;<>
                DB      #60                     ;┬г
                DB      #C6                     ;AND
                DB      #3A                     ;:

; Keywords assigned to the digits in extended mode.
; On the original keyboard those are remaining red keywords below the keys.
E_DIGITS:       DB      #D0                     ;FORMAT
                DB      #CE                     ;DEF FN
                DB      #A8                     ;FN
                DB      #CA                     ;LINE
                DB      #D3                     ;OPEN #
                DB      #D4                     ;CLOSE #
                DB      #D1                     ;MOVE
                DB      #D2                     ;ERASE
                DB      #A9                     ;POINT
                DB      #CF                     ;CAT

; Keyboard scanning
; returns 1 or 2 keys in DE
KEY_SCAN:       LD      L,#2F
                LD      DE,#FFFF
                LD      BC,#FEFE
KEY_LINE:       IN      A,(C)
                CPL
                AND     #1F
                JR      Z,KEY_DONE
                LD      H,A
                LD      A,L
KEY_3KEYS:      INC     D
                RET     NZ
KEY_BITS:       SUB     #08
                SRL     H
                JR      NC,KEY_BITS
                LD      D,E
                LD      E,A
                JR      NZ,KEY_3KEYS
KEY_DONE:       DEC     L
                RLC     B
                JR      C,KEY_LINE
                LD      A,D
                INC     A
                RET     Z
                CP      #28
                RET     Z
                CP      #19
                RET     Z
                LD      A,E
                LD      E,D
                LD      D,A
                CP      #18
                RET

; Scan keyboard and decode value
KEYBOARD:       CALL    KEY_SCAN
                RET     NZ
                LD      HL,#5C00
K_ST_LOOP:      BIT     7,(HL)
                JR      NZ,K_CH_SET
                INC     HL
                DEC     (HL)
                DEC     HL
                JR      NZ,K_CH_SET
                LD      (HL),#FF
K_CH_SET:       LD      A,L
                LD      HL,#5C04
                CP      L
                JR      NZ,K_ST_LOOP
                CALL    K_TEST
                RET     NC
                LD      HL,#5C00
                CP      (HL)
                JR      Z,K_REPEAT
                EX      DE,HL
                LD      HL,#5C04
                CP      (HL)
                JR      Z,K_REPEAT
                BIT     7,(HL)
                JR      NZ,K_NEW
                EX      DE,HL
                BIT     7,(HL)
                RET     Z
K_NEW:          LD      E,A
                LD      (HL),A
                INC     HL
                LD      (HL),#05
                INC     HL
                LD      A,(#5C09)
                LD      (HL),A
                INC     HL
                LD      C,(IY+#07)
                LD      D,(IY+#01)
                PUSH    HL
                CALL    K_DECODE
                POP     HL
                LD      (HL),A
K_END:          LD      (#5C08),A
                SET     5,(IY+#01)
                RET

; Repeat key routine
K_REPEAT:       INC     HL
                LD      (HL),#05
                INC     HL
                DEC     (HL)
                RET     NZ
                LD      A,(#5C0A)
                LD      (HL),A
                INC     HL
                LD      A,(HL)
                JR      K_END

; Test key value
K_TEST:         LD      B,D
                LD      D,#00
                LD      A,E
                CP      #27
                RET     NC
                CP      #18
                JR      NZ,K_MAIN
                BIT     7,B
                RET     NZ
K_MAIN:         LD      HL,MAIN_KEYS
                ADD     HL,DE
                LD      A,(HL)
                SCF
                RET

; Keyboard decoding
K_DECODE:       LD      A,E
                CP      #3A
                JR      C,K_DIGIT
                DEC     C
                JP      M,K_KLC_LET
                JR      Z,K_E_LET
                ADD     A,#4F
                RET

; Test if B is empty (i.e. not a shift)
; forward to K_LOOK_UP if neither shift
K_E_LET:        LD      HL,#01EB                ;E_UNSHIFT-#41
                INC     B
                JR      Z,K_LOOK_UP
                LD      HL,#0205                ;EXT_SHIFT-#41

; Prepare to index
K_LOOK_UP:      LD      D,#00
                ADD     HL,DE
                LD      A,(HL)
                RET

; Prepare base of SYM_CODES
K_KLC_LET:      LD      HL,#0229                ;SYM_CODES-#41
                BIT     0,B
                JR      Z,K_LOOK_UP
                BIT     3,D
                JR      Z,K_TOKENS
                BIT     3,(IY+#30)
                RET     NZ
                INC     B
                RET     NZ
                ADD     A,#20
                RET
; Add offset to main code to get tokens
K_TOKENS:       ADD     A,#A5
                RET

; Digits, space, enter and symbol shift decoding
K_DIGIT:        CP      #30
                RET     C
                DEC     C
                JP      M,K_KLC_DGT
                JR      NZ,K_GRA_DGT
                LD      HL,#0254                ;E_DIGITS-#30
                BIT     5,B
                JR      Z,K_LOOK_UP
                CP      #38
                JR      NC,K_8_AND_9
                SUB     #20
                INC     B
                RET     Z
                ADD     A,#08
                RET

; Digits 8 and 9 decoding
K_8_AND_9:      SUB     #36
                INC     B
                RET     Z
                ADD     A,#FE
                RET

; Graphics mode with digits
K_GRA_DGT:      LD      HL,#0230                ;CTL_CODES-#30
                CP      #39
                JR      Z,K_LOOK_UP
                CP      #30
                JR      Z,K_LOOK_UP
                AND     #07
                ADD     A,#80
                INC     B
                RET     Z
                XOR     #0F
                RET

; Digits in 'KLC' mode
K_KLC_DGT:      INC     B
                RET     Z
                BIT     5,B
                LD      HL,#0230                ;CTL_CODES-#30
                JR      NZ,K_LOOK_UP
                SUB     #10
                CP      #22
                JR      Z,K_AT_CHAR
                CP      #20
                RET     NZ
                LD      A,#5F
                RET

; Substitute ascii '@'
K_AT_CHAR:      LD      A,#40
                RET

; Routine to control loudspeaker
BEEPER:         DI
                LD      A,L
                SRL     L
                SRL     L
                CPL
                AND     #03
                LD      C,A
                LD      B,#00
                LD      IX,BE_IX_3
                ADD     IX,BC
                LD      A,(#5C48)
                AND     #38
                RRCA
                RRCA
                RRCA
                OR      #08
BE_IX_3:        NOP
                NOP
                NOP
                INC     B
                INC     C
BE_HL_LP:       DEC     C
                JR      NZ,BE_HL_LP
                LD      C,#3F
                DEC     B
                JP      NZ,BE_HL_LP
                XOR     #10
                OUT     (#FE),A
                LD      B,H
                LD      C,A
                BIT     4,A
                JR      NZ,BE_AGAIN
                LD      A,D
                OR      E
                JR      Z,BE_END
                LD      A,C
                LD      C,L
                DEC     DE
L_03F0:         JP      (IX)
BE_AGAIN:       LD      C,L
                INC     C
                JP      (IX)
BE_END:         EI
                RET

; Handle BEEP command
BEEP:           RST     #28                     ;FP_CALC
                DB      #31                     ;DUPLICATE - duplicate pitch
                DB      #27                     ;INT - convert to integer
                DB      #C0                     ;ST_MEM_0 - store integer pitch to memory 0
                DB      #03                     ;SUBTRACT - calculate fractional part of pitch = fp_pitch - int_pitch
                DB      #34                     ;STK_DATA - push constant
                DB      #EC                     ;Exponent: #7C, Bytes: 4 - constant = 0.05762265
                DB      #6C,#98,#1F,#F5         ;(#6C,#98,#1F,#F5)
                DB      #04                     ;MULTIPLY - compute:
                DB      #A1                     ;STK_ONE - 1 + 0.05762265 * fraction_part(pitch)
                DB      #0F                     ;ADDITION
                DB      #38                     ;END_CALC - leave on calc stack

                LD      HL,#5C92
                LD      A,(HL)
                AND     A
                JR      NZ,REPORT_B
                INC     HL
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                LD      A,B
                RLA
                SBC     A,A
                CP      C
                JR      NZ,REPORT_B
                INC     HL
                CP      (HL)
                JR      NZ,REPORT_B
                LD      A,B
                ADD     A,#3C
                JP      P,BE_I_OK
                JP      PO,REPORT_B
BE_I_OK:        LD      B,#FA
BE_OCTAVE:      INC     B
                SUB     #0C
                JR      NC,BE_OCTAVE
                ADD     A,#0C
                PUSH    BC
                LD      HL,SEMI_TONE
                CALL    LOC_MEM
                CALL    STACK_NUM

                RST     #28                     ;FP_CALC
                DB      #04                     ;MULTIPLY
                DB      #38                     ;END_CALC

                POP     AF
                ADD     A,(HL)
                LD      (HL),A

                RST     #28                     ;FP_CALC
                DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #31                     ;DUPLICATE
                DB      #38                     ;END_CALC

                CALL    FIND_INT1
                CP      #0B
                JR      NC,REPORT_B

                RST     #28                     ;FP_CALC
                DB      #E0                     ;GET_MEM_0
                DB      #04                     ;MULTIPLY
                DB      #E0                     ;GET_MEM_0
                DB      #34                     ;STK_DATA
                DB      #80                     ;Exponent #93, Bytes: 3
                DB      #43, #55, #9F, #80
                DB      #01                     ;EXCHANGE
                DB      #05                     ;DIVISION
                DB      #34                     ;STK_DATA
                DB      #35                     ;Exponent: #85, Bytes: 1
                DB      #71
                DB      #03                     ;SUBTRACT
                DB      #38                     ;END_CALC

                CALL    FIND_INT2
                PUSH    BC
                CALL    FIND_INT2
                POP     HL
                LD      D,B
                LD      E,C
                LD      A,D
                OR      E
                RET     Z
                DEC     DE
                JP      BEEPER

REPORT_B:       RST     #08                     ; Error report
                DB      #0A                     ; Integer out of range

; Semi-tone table.
; Holds frequencies corresponding to semitones in middle octave.
SEMI_TONE:      DB      #89, #02, #D0, #12, #86
                DB      #89, #0A, #97, #60, #75
                DB      #89, #12, #D5, #17, #1F
                DB      #89, #1B, #90, #41, #02
                DB      #89, #24, #D0, #53, #CA
                DB      #89, #2E, #9D, #36, #B1
                DB      #89, #38, #FF, #49, #3E
                DB      #89, #43, #FF, #6A, #73
                DB      #89, #4F, #A7, #00, #54
                DB      #89, #5C, #00, #00, #00
                DB      #89, #69, #14, #F6, #24
                DB      #89, #76, #F1, #10, #05

; BSROM - file name is optional now.
; There was ZX81_NAME routine at this place, but it was not used anyway.
NONAME:         RST     #18
                LD      HL,NNTAB
                LD      BC,#0005
                CPIR
                JP      NZ,EXPT_EXP
                LD      C,#00
                JP      SL_OVER1
NNTAB:          DB      #3A
                DW      #AA0D
                DW      #E4AF
                DW      #0000

; Save header and program or data
SA_BYTES:       LD      HL,SA_LD_RET
                PUSH    HL
SA_BYTES1:      LD      HL,#1F80
                BIT     7,A
                JR      Z,SA_FLAG
                LD      HL,#0C98
SA_FLAG:        EX      AF,AF'
                INC     DE
                DEC     IX
                DI
                LD      A,#02
                LD      B,A
SA_LEADER:      DJNZ    SA_LEADER
                OUT     (#FE),A
                XOR     #0F
                LD      B,#A4
                DEC     L
                JR      NZ,SA_LEADER
                DEC     B
                DEC     H
                JP      P,SA_LEADER
                LD      B,#2F
SA_SYNC_1:      DJNZ    SA_SYNC_1
                OUT     (#FE),A
                LD      A,#0D
                LD      B,#37
SA_SYNC_2:      DJNZ    SA_SYNC_2
                OUT     (#FE),A
                LD      BC,#3B0E                ; B=#3B time; C=#0E YELLOW, MIC OFF.
                EX      AF,AF'

                LD      L,A
                JP      SA_START

SA_LOOP:        LD      A,D
                OR      E
                JR      Z,SA_PARITY
                LD      L,(IX+#00)
SA_LOOP_P:      LD      A,H
                XOR     L
SA_START:       LD      H,A
                LD      A,#01
                SCF
                JP      SA_8_BITS

SA_PARITY:      LD      L,H
                JR      SA_LOOP_P

SA_BIT_2:       LD      A,C
                BIT     7,B
SA_BIT_1:       DJNZ    SA_BIT_1
                JR      NC,SA_OUT
                LD      B,#42
SA_SET:         DJNZ    SA_SET
SA_OUT:         OUT     (#FE),A
                LD      B,#3E
                JR      NZ,SA_BIT_2
                DEC     B
                XOR     A
                INC     A
SA_8_BITS:      RL      L
                JP      NZ,SA_BIT_1
                DEC     DE
                INC     IX
                LD      B,#31
                LD      A,#7F
                IN      A,(#FE)
                RRA
                RET     NC
                LD      A,D
                INC     A
                JP      NZ,SA_LOOP
                LD      B,#3B
SA_DELAY:       DJNZ    SA_DELAY
                RET

; Reset border nad check BREAK for LOAD and SAVE
SA_LD_RET:      PUSH    AF
                LD      A,(#5C48)
                AND     #38
                RRCA
                RRCA
                RRCA
                OUT     (#FE),A
                LD      A,#7F
                IN      A,(#FE)
                RRA
                EI
                JR      C,SA_LD_END
REPORT_DA:      RST     #08                     ; Error report
                DB      #0C                     ; BREAK - CONT repeats
SA_LD_END:      POP     AF
                RET

; Load header or data
LD_BYTES:       INC     D
                EX      AF,AF'
                DEC     D
                DI
                LD      A,#0F
                OUT     (#FE),A
                LD      HL,SA_LD_RET
                PUSH    HL
                IN      A,(#FE)
                RRA
LD_BYTES1:      AND     #20
                OR      #02
                LD      C,A
                CP      A
LD_BREAK:       RET     NZ
LD_START:       CALL    LD_EDGE_1
                JR      NC,LD_BREAK
                LD      HL,#0115                ; BSROM - short delay (was #0415 in orig. ROM)
LD_WAIT:        DJNZ    LD_WAIT
                DEC     HL
                LD      A,H
                OR      L
                JR      NZ,LD_WAIT
                CALL    LD_EDGE_2
                JR      NC,LD_BREAK
LD_LEADER:      LD      B,#9C
                CALL    LD_EDGE_2
                JR      NC,LD_BREAK
                LD      A,#C6
                CP      B
                JR      NC,LD_START
                INC     H
                JR      NZ,LD_LEADER
LD_SYNC:        LD      B,#C9
                CALL    LD_EDGE_1
                JR      NC,LD_BREAK
                LD      A,B
                CP      #D4
                JR      NC,LD_SYNC
                CALL    LD_EDGE_1
                RET     NC
                LD      A,C
                XOR     #03
                LD      C,A
                LD      H,#00
                LD      B,#B0
                JR      LD_MARKER

LD_LOOP:        EX      AF,AF'

                JR      NZ,LD_FLAG
                JR      NC,LD_VERIFY
                LD      (IX+#00),L
                JR      LD_NEXT

LD_FLAG:        RL      C
                XOR     L
                RET     NZ
                LD      A,C
                RRA
                LD      C,A
                INC     DE
                JR      LD_DEC

LD_VERIFY:      LD      A,(IX+#00)
                XOR     L
                RET     NZ
LD_NEXT:        INC     IX
LD_DEC:         DEC     DE
                EX      AF,AF'
                LD      B,#B2
LD_MARKER:      LD      L,#01
LD_8_BITS:      CALL    LD_EDGE_2
                RET     NC
                LD      A,#CB
                CP      B
                RL      L
                LD      B,#B0
                JP      NC,LD_8_BITS
                LD      A,H
                XOR     L
                LD      H,A
                LD      A,D
                OR      E
                JR      NZ,LD_LOOP
                LD      A,H
                CP      #01
                RET

; Check signal being loaded
LD_EDGE_2:      CALL    LD_EDGE_1
                RET     NC
LD_EDGE_1:      LD      A,#16
LD_DELAY:       DEC     A
                JR      NZ,LD_DELAY
                AND     A
LD_SAMPLE:      INC     B
                RET     Z
                LD      A,#7F
                IN      A,(#FE)
                RRA
                RET     NC
                XOR     C
                AND     #20
                JR      Z,LD_SAMPLE
                LD      A,C
                CPL
                LD      C,A
                AND     #07
                OR      #08
                OUT     (#FE),A
                SCF
                RET

; Entry point for tape commands
SAVE_ETC:       POP     AF
                LD      A,(#5C74)
                SUB     #E0
                LD      (#5C74),A
                CALL    NONAME                  ; BSROM - file name is optional now
                CALL    SYNTAX_Z
                JR      Z,SA_DATA
                LD      BC,#0011
                LD      A,(#5C74)
                AND     A
                JR      Z,SA_SPACE
                LD      C,#22
SA_SPACE:       RST     #30
                PUSH    DE
                POP     IX
                LD      B,#0B
                LD      A,#20
SA_BLANK:       LD      (DE),A
                INC     DE
                DJNZ    SA_BLANK
                LD      (IX+#01),#FF
                CALL    STK_FETCH
                LD      HL,#FFF6
                DEC     BC
                ADD     HL,BC
                INC     BC
                JR      NC,SA_NAME
                LD      A,(#5C74)
                AND     A
                JR      NZ,SA_NULL
REPORT_FA:      RST     #08                     ; Error report
                DB      #0E                     ; Invalid file name
SA_NULL:        LD      A,B
                OR      C
                JR      Z,SA_DATA
                LD      BC,#000A
SA_NAME:        PUSH    IX
                POP     HL
                INC     HL
                EX      DE,HL
                LDIR
SA_DATA:        RST     #18
                CP      #E4
                JR      NZ,SA_SCR
                LD      A,(#5C74)
                CP      #03
                JP      Z,REPORT_C
                RST     #20
                CALL    LOOK_VARS
                SET     7,C
                JR      NC,SA_V_OLD
                LD      HL,#0000
                LD      A,(#5C74)
                DEC     A
                JR      Z,SA_V_NEW
REPORT_2A:      RST     #08                     ; Error report
                DB      #01                     ; Variable not found
SA_V_OLD:       JP      NZ,REPORT_C
                CALL    SYNTAX_Z
                JR      Z,SA_DATA_1
                INC     HL
                LD      A,(HL)
                LD      (IX+#0B),A
                INC     HL
                LD      A,(HL)
                LD      (IX+#0C),A
                INC     HL
SA_V_NEW:       LD      (IX+#0E),C
                LD      A,#01
                BIT     6,C
                JR      Z,SA_V_TYPE
                INC     A
SA_V_TYPE:      LD      (IX+#00),A
SA_DATA_1:      EX      DE,HL
                RST     #20
                CP      #29
                JR      NZ,SA_V_OLD
                RST     #20
                CALL    CHECK_END
                EX      DE,HL
                JP      SA_ALL

SA_SCR:         CP      #AA
                JR      NZ,SA_CODE
                LD      A,(#5C74)
                CP      #03
                JP      Z,REPORT_C
                RST     #20
                CALL    CHECK_END
                LD      (IX+#0B),#00
                LD      (IX+#0C),#1B
                LD      HL,#4000
                LD      (IX+#0D),L
                LD      (IX+#0E),H
                JR      SA_TYPE_3

SA_CODE:        CP      #AF
                JR      NZ,SA_LINE
                LD      A,(#5C74)
                CP      #03
                JP      Z,REPORT_C
                RST     #20
                CALL    PR_ST_END
                JR      NZ,SA_CODE_1
                LD      A,(#5C74)
                AND     A
                JP      Z,REPORT_C
                CALL    USE_ZERO
                JR      SA_CODE_2

SA_CODE_1:      CALL    EXPT_1NUM
                RST     #18
                CP      #2C
                JR      Z,SA_CODE_3
                LD      A,(#5C74)
                AND     A
                JP      Z,REPORT_C
SA_CODE_2:      CALL    USE_ZERO
                JR      SA_CODE_4

SA_CODE_3:      RST     #20
                CALL    EXPT_1NUM
SA_CODE_4:      CALL    CHECK_END
                CALL    FIND_INT2
                LD      (IX+#0B),C
                LD      (IX+#0C),B
                CALL    FIND_INT2
                LD      (IX+#0D),C
                LD      (IX+#0E),B
                LD      H,B
                LD      L,C
SA_TYPE_3:      LD      (IX+#00),#03
                JR      SA_ALL

SA_LINE:        CP      #CA
                JR      Z,SA_LINE_1
                CALL    CHECK_END
                LD      (IX+#0E),#80
                JR      SA_TYPE_0

SA_LINE_1:      LD      A,(#5C74)
                AND     A
                JP      NZ,REPORT_C
                RST     #20
                CALL    EXPT_1NUM
                CALL    CHECK_END
                CALL    FIND_INT2
                LD      (IX+#0D),C
                LD      (IX+#0E),B
SA_TYPE_0:      LD      (IX+#00),#00
                LD      HL,(#5C59)
                LD      DE,(#5C53)
                SCF
                SBC     HL,DE
                LD      (IX+#0B),L
                LD      (IX+#0C),H
                LD      HL,(#5C4B)
                SBC     HL,DE
                LD      (IX+#0F),L
                LD      (IX+#10),H
                EX      DE,HL
SA_ALL:         LD      A,(#5C74)
                AND     A
                JP      Z,SA_CONTRL
                PUSH    HL
                LD      BC,#0011
                ADD     IX,BC
LD_LOOK_H:      PUSH    IX
                LD      DE,#0011
                XOR     A
                SCF
                CALL    LD_BYTES
                POP     IX
                JR      NC,LD_LOOK_H
                LD      A,#FE
                CALL    CHAN_OPEN
                LD      (IY+#52),#FF            ; BSROM - fixed "scroll?" troubles when tape header is shown, was LD (IY+$52),$03
                LD      C,#80
                LD      A,(IX+#00)
                CP      (IX-#11)
                JR      NZ,LD_TYPE
                LD      C,#F6
LD_TYPE:        CP      #04
                JR      NC,LD_LOOK_H
                LD      DE,TAPE_MSGS2
                PUSH    BC
                CALL    PO_MSG
                POP     BC
                PUSH    IX
                POP     DE
                LD      HL,#FFF0
                ADD     HL,DE
                LD      B,#0A
                LD      A,(HL)
                INC     A
                JR      NZ,LD_NAME
                LD      A,C
                ADD     A,B
                LD      C,A
LD_NAME:        INC     DE
                LD      A,(DE)
                CP      (HL)
                INC     HL
                JR      NZ,LD_CH_PR
                INC     C
LD_CH_PR:       RST     #10
                DJNZ    LD_NAME
                BIT     7,C
                JR      NZ,LD_LOOK_H
                LD      A,#0D
                RST     #10
                POP     HL
                LD      A,(IX+#00)
                CP      #03
                JR      Z,VR_CONTROL
                LD      A,(#5C74)
                DEC     A
                JP      Z,LD_CONTRL
                CP      #02
                JP      Z,ME_CONTRL
VR_CONTROL:     PUSH    HL                      ; Handle VERIFY control
                LD      L,(IX-#06)
                LD      H,(IX-#05)
                LD      E,(IX+#0B)
                LD      D,(IX+#0C)
                LD      A,H
                OR      L
                JR      Z,VR_CONT_1
                SBC     HL,DE
                JR      C,REPORT_R
                JR      Z,VR_CONT_1
                LD      A,(IX+#00)
                CP      #03
                JR      NZ,REPORT_R
VR_CONT_1:      POP     HL
                LD      A,H
                OR      L
                JR      NZ,VR_CONT_2
                LD      L,(IX+#0D)
                LD      H,(IX+#0E)
VR_CONT_2:      PUSH    HL
                POP     IX
                LD      A,(#5C74)
                CP      #02
                SCF
                JR      NZ,VR_CONT_3
                AND     A
VR_CONT_3:      LD      A,#FF
LD_BLOCK:       CALL    LD_BYTES                ; Load a block of data
                RET     C
REPORT_R:       RST     #08                     ; Error report
                DB      #1A                     ; Tape loading error
LD_CONTRL:      LD      E,(IX+#0B)              ; Handle LOAD control
                LD      D,(IX+#0C)
                PUSH    HL
                LD      A,H
                OR      L
                JR      NZ,LD_CONT_1
                INC     DE
                INC     DE
                INC     DE
                EX      DE,HL
                JR      LD_CONT_2

LD_CONT_1:      LD      L,(IX-#06)
                LD      H,(IX-#05)
                EX      DE,HL
                SCF
                SBC     HL,DE
                JR      C,LD_DATA
LD_CONT_2:      LD      DE,#0005
                ADD     HL,DE
                LD      B,H
                LD      C,L
                CALL    TEST_ROOM
LD_DATA:        POP     HL
                LD      A,(IX+#00)
                AND     A
                JR      Z,LD_PROG
                LD      A,H
                OR      L
                JR      Z,LD_DATA_1
                DEC     HL
                LD      B,(HL)
                DEC     HL
                LD      C,(HL)
                DEC     HL
                INC     BC
                INC     BC
                INC     BC
                LD      (#5C5F),IX
                CALL    RECLAIM_2
                LD      IX,(#5C5F)
LD_DATA_1:      LD      HL,(#5C59)
                DEC     HL
                LD      C,(IX+#0B)
                LD      B,(IX+#0C)
                PUSH    BC
                INC     BC
                INC     BC
                INC     BC
                LD      A,(IX-#03)
                PUSH    AF
                CALL    MAKE_ROOM
                INC     HL
                POP     AF
                LD      (HL),A
                POP     DE
                INC     HL
                LD      (HL),E
                INC     HL
                LD      (HL),D
                INC     HL
                PUSH    HL
                POP     IX
                SCF
                LD      A,#FF
                JP      LD_BLOCK

LD_PROG:        EX      DE,HL
                LD      HL,(#5C59)
                DEC     HL
                LD      (#5C5F),IX
                LD      C,(IX+#0B)
                LD      B,(IX+#0C)
                PUSH    BC
                CALL    RECLAIM_1
                POP     BC
                PUSH    HL
                PUSH    BC
                CALL    MAKE_ROOM
                LD      IX,(#5C5F)
                INC     HL
                LD      C,(IX+#0F)
                LD      B,(IX+#10)
                ADD     HL,BC
                LD      (#5C4B),HL
                LD      H,(IX+#0E)
                LD      A,H
                AND     #C0
                JR      NZ,LD_PROG_1
                LD      L,(IX+#0D)
                LD      (#5C42),HL
                LD      (IY+#0A),#00
LD_PROG_1:      POP     DE
                POP     IX
                SCF
                LD      A,#FF
                JP      LD_BLOCK

; Handle MERGE control
ME_CONTRL:      LD      C,(IX+#0B)
                LD      B,(IX+#0C)
                PUSH    BC
                INC     BC
                RST     #30
                LD      (HL),#80
                EX      DE,HL
                POP     DE
                PUSH    HL
                PUSH    HL
                POP     IX
                SCF
                LD      A,#FF
                CALL    LD_BLOCK
                POP     HL
                LD      DE,(#5C53)
ME_NEW_LP:      LD      A,(HL)
                AND     #C0
                JR      NZ,ME_VAR_LP
ME_OLD_LP:      LD      A,(DE)
                INC     DE
                CP      (HL)
                INC     HL
                JR      NZ,ME_OLD_L1
                LD      A,(DE)
                CP      (HL)
ME_OLD_L1:      DEC     DE
                DEC     HL
                JR      NC,ME_NEW_L2
                PUSH    HL
                EX      DE,HL
                CALL    NEXT_ONE
                POP     HL
                JR      ME_OLD_LP

ME_NEW_L2:      CALL    ME_ENTER
                JR      ME_NEW_LP

ME_VAR_LP:      LD      A,(HL)
                LD      C,A
                CP      #80
                RET     Z
                PUSH    HL
                LD      HL,(#5C4B)
ME_OLD_VP:      LD      A,(HL)
                CP      #80
                JR      Z,ME_VAR_L2
                CP      C
                JR      Z,ME_OLD_V2
ME_OLD_V1:      PUSH    BC
                CALL    NEXT_ONE
                POP     BC
                EX      DE,HL
                JR      ME_OLD_VP

ME_OLD_V2:      AND     #E0
                CP      #A0
                JR      NZ,ME_VAR_L1
                POP     DE
                PUSH    DE
                PUSH    HL
ME_OLD_V3:      INC     HL
                INC     DE
                LD      A,(DE)
                CP      (HL)
                JR      NZ,ME_OLD_V4
                RLA
                JR      NC,ME_OLD_V3
                POP     HL
                JR      ME_VAR_L1

ME_OLD_V4:      POP     HL
                JR      ME_OLD_V1

ME_VAR_L1:      LD      A,#FF
ME_VAR_L2:      POP     DE
                EX      DE,HL
                INC     A
                SCF
                CALL    ME_ENTER
                JR      ME_VAR_LP

; Merge a line or variable
ME_ENTER:       JR      NZ,ME_ENT_1
                EX      AF,AF'

                LD      (#5C5F),HL
                EX      DE,HL
                CALL    NEXT_ONE
                CALL    RECLAIM_2
                EX      DE,HL
                LD      HL,(#5C5F)
                EX      AF,AF'
ME_ENT_1:       EX      AF,AF'

                PUSH    DE
                CALL    NEXT_ONE
                LD      (#5C5F),HL
                LD      HL,(#5C53)
                EX      (SP),HL
                PUSH    BC
                EX      AF,AF'
                JR      C,ME_ENT_2
                DEC     HL
                CALL    MAKE_ROOM
                INC     HL
                JR      ME_ENT_3

ME_ENT_2:       CALL    MAKE_ROOM
ME_ENT_3:       INC     HL
                POP     BC
                POP     DE
                LD      (#5C53),DE
                LD      DE,(#5C5F)
                PUSH    BC
                PUSH    DE
                EX      DE,HL
                LDIR
                POP     HL
                POP     BC
                PUSH    DE
                CALL    RECLAIM_2
                POP     DE
                RET

; Handle SAVE control
SA_CONTRL:      PUSH    HL
                LD      A,#FD
                CALL    CHAN_OPEN
                XOR     A
                LD      DE,TAPE_MSGS
                CALL    PO_MSG
                SET     5,(IY+#02)
                CALL    WAIT_KEY
                PUSH    IX
                LD      DE,#0011
                XOR     A
                CALL    SA_BYTES
                POP     IX
                LD      B,#32
SA_1_SEC:       HALT
                DJNZ    SA_1_SEC
                LD      E,(IX+#0B)
                LD      D,(IX+#0C)
                POP     IX                      ; BSROM - LD A,#FF and POP IX swapped
                LD      A,#FF
                JP      SA_BYTES

; Tape mesages
TAPE_MSGS:      DB      #80
                DC      "Press REC & PLAY, then any key."
TAPE_MSGS2:     EQU     $-1
                DB      #0D
                DC      "Program: "
                DB      #0D
                DC      "Number array: "
                DB      #0D
                DC      "Character array: "
                DB      #0D
                DC      "Bytes: "

; Genereal PRINT routine
PRINT_OUT:      CALL    DISPL                   ; BSROM - disabled autolist of control codes
                CP      #1E
                JP      NC,PO_ABLE
                CP      #06
                JR      C,PO_QUEST
                CP      #18
                JR      NC,PO_QUEST
                LD      HL,CTLCHRTAB-6
                LD      E,A
                LD      D,#00
                ADD     HL,DE
                LD      E,(HL)
                ADD     HL,DE
                PUSH    HL
                JP      PO_FETCH

;Control character table
CTLCHRTAB:      DB      #4E                     ; PO_COMMA
                DB      #57                     ; PO_QUEST
                DB      #10                     ; PO_BACK_1
                DB      #29                     ; PO_RIGHT
                DB      #54                     ; PO_QUEST
                DB      #53                     ; PO_QUEST
                DB      #52                     ; PO_QUEST
                DB      #37                     ; PO_ENTER
                DB      #50                     ; PO_QUEST
                DB      #4F                     ; PO_QUEST
                DB      #5F                     ; PO_1_OPER
                DB      #5E                     ; PO_1_OPER
                DB      #5D                     ; PO_1_OPER
                DB      #5C                     ; PO_1_OPER
                DB      #5B                     ; PO_1_OPER
                DB      #5A                     ; PO_1_OPER
                DB      #54                     ; PO_2_OPER
                DB      #53                     ; PO_2_OPER

; Cursor left routine
PO_BACK_1:      INC     C
                LD      A,#22
                CP      C
                JR      NZ,PO_BACK_3
                BIT     1,(IY+#01)
                JR      NZ,PO_BACK_2
                INC     B
                LD      C,#02
                LD      A,#19                   ; BSROM - bugfix - was LD A,#18
                CP      B
                JR      NZ,PO_BACK_3
                DEC     B
PO_BACK_2:      LD      C,#21
PO_BACK_3:      JP      CL_SET

; Cursor right routine
PO_RIGHT:       LD      A,(#5C91)
                PUSH    AF
                LD      (IY+#57),#01
                LD      A,#20
                CALL    PO_ABLE                 ; BSROM - bugfix - was CALL PO_BACK
                POP     AF
                LD      (#5C91),A
                RET

; Carriage return / Enter
PO_ENTER:       BIT     1,(IY+#01)
                JP      NZ,COPY_BUFF
                LD      C,#21
                CALL    PO_SCR
                DEC     B
                JP      CL_SET

; Print comma
PO_COMMA:       CALL    PO_FETCH
                LD      A,C
                DEC     A
                DEC     A
                AND     #10
                JR      PO_FILL

; Print question mark
PO_QUEST:       LD      A,#3F
                JR      PO_ABLE

; Control characters with operands
PO_TV_2:        LD      DE,PO_CONT
                LD      (#5C0F),A
                JR      PO_CHANGE

PO_2_OPER:      LD      DE,PO_TV_2
                JR      PO_TV_1

PO_1_OPER:      LD      DE,PO_CONT
PO_TV_1:        LD      (#5C0E),A
PO_CHANGE:      LD      HL,(#5C51)
                LD      (HL),E
                INC     HL
                LD      (HL),D
                RET

PO_CONT:        LD      DE,PRINT_OUT
                CALL    PO_CHANGE
                LD      HL,(#5C0E)
                LD      D,A
                LD      A,L
                CP      #16
                JP      C,CO_TEMP_5
                JR      NZ,PO_TAB
                LD      B,H
                LD      C,D
                LD      A,#1F
                SUB     C
                JR      C,PO_AT_ERR
                ADD     A,#02
                LD      C,A
                BIT     1,(IY+#01)
                JR      NZ,PO_AT_SET
                LD      A,#16
                SUB     B
PO_AT_ERR:      JP      C,REPORT_BB
                INC     A
                LD      B,A
                INC     B
                BIT     0,(IY+#02)
                JP      NZ,PO_SCR
                CP      (IY+#31)
                JP      C,REPORT_5
PO_AT_SET:      JP      CL_SET

PO_TAB:         LD      A,H
PO_FILL:        CALL    PO_FETCH
                ADD     A,C
                DEC     A
                AND     #1F
                RET     Z
                LD      D,A
                SET     0,(IY+#01)
PO_SPACE:       LD      A,#20
                CALL    PO_SAVE
                DEC     D
                JR      NZ,PO_SPACE
                RET

; Print printable character(s)
PO_ABLE:        CALL    PO_ANY

; Store line, column and pixel address
PO_STORE:       BIT     1,(IY+#01)
                JR      NZ,PO_ST_PR
                BIT     0,(IY+#02)
                JR      NZ,PO_ST_E
                LD      (#5C88),BC
                LD      (#5C84),HL
                RET

PO_ST_E:        LD      (#5C8A),BC
                LD      (#5C82),BC
                LD      (#5C86),HL
                RET

PO_ST_PR:       LD      (IY+#45),C
                LD      (#5C80),HL
                RET

; Fetch position parameters
PO_FETCH:       BIT     1,(IY+#01)
                JR      NZ,PO_F_FR
                LD      BC,(#5C88)
                LD      HL,(#5C84)
                BIT     0,(IY+#02)
                RET     Z
                LD      BC,(#5C8A)
                LD      HL,(#5C86)
                RET

PO_F_FR:        LD      C,(IY+#45)
                LD      HL,(#5C80)
                RET

; Print any character
PO_ANY:         CP      #80
                JR      C,PO_CHAR
                CP      #90
                JR      NC,PO_T_UDG
                LD      B,A
                CALL    PO_GR_1
                CALL    PO_FETCH
                LD      DE,#5C92
                JR      PR_ALL

PO_GR_1:        LD      HL,#5C92
                CALL    PO_GR_2
PO_GR_2:        RR      B
                SBC     A,A
                AND     #0F
                LD      C,A
                RR      B
                SBC     A,A
                AND     #F0
                OR      C
                LD      C,#04
PO_GR_3:        LD      (HL),A
                INC     HL
                DEC     C
                JR      NZ,PO_GR_3
                RET

PO_T_UDG:       SUB     #A5
                JR      NC,PO_T
                ADD     A,#15
                PUSH    BC
                LD      BC,(#5C7B)
                JR      PO_CHAR_2

PO_T:           CALL    PO_TOKENS
                JP      PO_FETCH

PO_CHAR:        PUSH    BC
                LD      BC,(#5C36)
PO_CHAR_2:      EX      DE,HL
                LD      HL,#5C3B
                RES     0,(HL)
                CP      #20
                JR      NZ,PO_CHAR_3
                SET     0,(HL)
PO_CHAR_3:      LD      H,#00
                LD      L,A
                ADD     HL,HL
                ADD     HL,HL
                ADD     HL,HL
                ADD     HL,BC
                POP     BC
                EX      DE,HL
PR_ALL:         LD      A,C                     ; Print all characters
                DEC     A
                LD      A,#21
                JR      NZ,PR_ALL_1
                DEC     B
                LD      C,A
                BIT     1,(IY+#01)
                JR      Z,PR_ALL_1
                PUSH    DE
                CALL    COPY_BUFF
                POP     DE
                LD      A,C
PR_ALL_1:       CP      C
                PUSH    DE
                CALL    Z,PO_SCR
                POP     DE
                PUSH    BC
                PUSH    HL
                LD      A,(#5C91)
                LD      B,#FF
                RRA
                JR      C,PR_ALL_2
                INC     B
PR_ALL_2:       RRA
                RRA
                SBC     A,A
                LD      C,A
                LD      A,#08
                AND     A
                BIT     1,(IY+#01)
                JR      Z,PR_ALL_3
                SET     1,(IY+#30)
                SCF
PR_ALL_3:       EX      DE,HL
PR_ALL_4:       EX      AF,AF'

                LD      A,(DE)
                AND     B
                XOR     (HL)
                XOR     C
                LD      (DE),A
                EX      AF,AF'
                JR      C,PR_ALL_6
                INC     D
PR_ALL_5:       INC     HL
                DEC     A
                JR      NZ,PR_ALL_4
                EX      DE,HL
                DEC     H
                BIT     1,(IY+#01)
                CALL    Z,PO_ATTR
                POP     HL
                POP     BC
                DEC     C
                INC     HL
                RET

PR_ALL_6:       EX      AF,AF'

                LD      A,#20
                ADD     A,E
                LD      E,A
                EX      AF,AF'
                JR      PR_ALL_5

; Set attribute
PO_ATTR:        LD      A,H
                RRCA
                RRCA
                RRCA
                AND     #03
                OR      #58
                LD      H,A
                LD      DE,(#5C8F)
                LD      A,(HL)
                XOR     E
                AND     D
                XOR     E
                BIT     6,(IY+#57)
                JR      Z,PO_ATTR_1
                AND     #C7
                BIT     2,A
                JR      NZ,PO_ATTR_1
                XOR     #38
PO_ATTR_1:      BIT     4,(IY+#57)
                JR      Z,PO_ATTR_2
                AND     #F8
                BIT     5,A
                JR      NZ,PO_ATTR_2
                XOR     #07
PO_ATTR_2:      LD      (HL),A
                RET

; Message printing (boot-up, tape, scroll, error reports)
PO_MSG:         PUSH    HL
                LD      H,#00
                EX      (SP),HL
                JR      PO_TABLE

PO_TOKENS:      LD      DE,TKN_TABLE
PO_TOKENS1:     PUSH    AF
PO_TABLE:       CALL    PO_SEARCH
                JR      C,PO_EACH
                LD      A,#20
                BIT     0,(IY+#01)
                CALL    Z,PO_SAVE
PO_EACH:        LD      A,(DE)
                AND     #7F
                CALL    PO_SAVE
                LD      A,(DE)
                INC     DE
                ADD     A,A
                JR      NC,PO_EACH
                POP     DE
                CP      #48
                JR      Z,PO_TR_SP
                CP      #82
                RET     C
PO_TR_SP:       LD      A,D
                CP      #03
                RET     C
                LD      A,#20
PO_SAVE:        PUSH    DE                      ; Handle recursive printing
                EXX
                RST     #10
                EXX
                POP     DE
                RET

; Token table search
PO_SEARCH:      PUSH    AF
                EX      DE,HL
                INC     A
PO_STEP:        BIT     7,(HL)
                INC     HL
                JR      Z,PO_STEP
                DEC     A
                JR      NZ,PO_STEP
                EX      DE,HL
                POP     AF
                CP      #20
                RET     C
                LD      A,(DE)
                SUB     #41
                RET

; Test for scroll
PO_SCR:         BIT     1,(IY+#01)
                RET     NZ
                LD      DE,CL_SET
                PUSH    DE
                LD      A,B
                BIT     0,(IY+#02)
                JP      NZ,PO_SCR_4
                CP      (IY+#31)
                JR      C,REPORT_5
                RET     NZ
                BIT     4,(IY+#02)
                JR      Z,PO_SCR_2
                LD      E,(IY+#2D)
                DEC     E
                JR      Z,PO_SCR_3
                LD      A,#00
                CALL    CHAN_OPEN
                LD      SP,(#5C3F)
                RES     4,(IY+#02)
                RET

REPORT_5:       RST     #08                     ; Error report
                DB      #04                     ; Out of screen
PO_SCR_2:       DEC     (IY+#52)
                JR      NZ,PO_SCR_3
                LD      A,#18
                SUB     B
                LD      (#5C8C),A
                LD      HL,(#5C8F)
                PUSH    HL
                LD      A,(#5C91)
                PUSH    AF
                LD      A,#FD
                CALL    CHAN_OPEN
                XOR     A
                LD      DE,SCRL_MSG
                CALL    PO_MSG
                SET     5,(IY+#02)
                LD      HL,#5C3B
                SET     3,(HL)
                RES     5,(HL)
                EXX
                CALL    WAIT_KEY
                EXX
                CP      #20
                JR      Z,REPORT_D
                CP      #E2
                JR      Z,REPORT_D
                OR      #20
                CP      #6E
                JR      Z,REPORT_D
                LD      A,#FE
                CALL    CHAN_OPEN
                POP     AF
                LD      (#5C91),A
                POP     HL
                LD      (#5C8F),HL
PO_SCR_3:       CALL    CL_SC_ALL
                LD      B,(IY+#31)
                INC     B
                LD      C,#21
                PUSH    BC
                CALL    CL_ADDR
                LD      A,H
                RRCA
                RRCA
                RRCA
                AND     #03
                OR      #58
                LD      H,A
                LD      DE,#5AE0
                LD      A,(DE)
                LD      C,(HL)
                LD      B,#20
                EX      DE,HL
PO_SCR_3A:      LD      (DE),A
                LD      (HL),C
                INC     DE
                INC     HL
                DJNZ    PO_SCR_3A
                POP     BC
                RET

SCRL_MSG:       DB      #80
                DC      "scroll?"

REPORT_D:       RST     #08                     ; Error report
                DB      #0C                     ; BREAK - CONT repeats
PO_SCR_4:       CP      #02
                JR      C,REPORT_5
                ADD     A,(IY+#31)
                SUB     #19
                RET     NC
                NEG
                PUSH    BC
                LD      B,A
                LD      HL,(#5C8F)
                PUSH    HL
                LD      HL,(#5C91)
                PUSH    HL
                CALL    TEMPS
                LD      A,B
PO_SCR_4A:      PUSH    AF
                LD      HL,#5C6B
                LD      B,(HL)
                LD      A,B
                INC     A
                LD      (HL),A
                LD      HL,#5C89
                CP      (HL)
                JR      C,PO_SCR_4B
                INC     (HL)
                LD      B,#18
PO_SCR_4B:      CALL    CL_SCROLL
                POP     AF
                DEC     A
                JR      NZ,PO_SCR_4A
                POP     HL
                LD      (IY+#57),L
                POP     HL
                LD      (#5C8F),HL
                LD      BC,(#5C88)
                RES     0,(IY+#02)
                CALL    CL_SET
                SET     0,(IY+#02)
                POP     BC
                RET

; Copy temporary items
TEMPS:          XOR     A
                LD      HL,(#5C8D)
                BIT     0,(IY+#02)
                JR      Z,TEMPS_1
                LD      H,A
                LD      L,(IY+#0E)
TEMPS_1:        LD      (#5C8F),HL
                LD      HL,#5C91
                JR      NZ,TEMPS_2
                LD      A,(HL)
                RRCA
TEMPS_2:        XOR     (HL)
                AND     #55
                XOR     (HL)
                LD      (HL),A
                RET

; Handle CLS command
CLS:            CALL    CL_ALL
CLS_LOWER:      LD      HL,#5C3C
                RES     5,(HL)
                SET     0,(HL)
                CALL    TEMPS
                LD      B,(IY+#31)
                CALL    CL_LINE
                LD      HL,#5AC0
                LD      A,(#5C8D)
                DEC     B
                JR      CLS_3

CLS_1:          LD      C,#20
CLS_2:          DEC     HL
                LD      (HL),A
                DEC     C
                JR      NZ,CLS_2
CLS_3:          DJNZ    CLS_1
                LD      (IY+#31),#02
CL_CHAN:        LD      A,#FD
                CALL    CHAN_OPEN
                LD      HL,(#5C51)
                LD      DE,PRINT_OUT
                AND     A
CL_CHAN_A:      LD      (HL),E
                INC     HL
                LD      (HL),D
                INC     HL
                LD      DE,KEY_INPUT
                CCF
                JR      C,CL_CHAN_A
                LD      BC,#1721
                JR      CL_SET

; Clear display area
CL_ALL:         LD      HL,#0000
                LD      (#5C7D),HL
                RES     0,(IY+#30)
                CALL    CL_CHAN
                LD      A,#FE
                CALL    CHAN_OPEN
                CALL    TEMPS
                LD      B,#18
                CALL    CL_LINE
                LD      HL,(#5C51)
                LD      DE,PRINT_OUT
                LD      (HL),E
                INC     HL
                LD      (HL),D
                LD      (IY+#52),#01
                LD      BC,#1821
CL_SET:         LD      HL,#5B00                ; Set line and column numbers
                BIT     1,(IY+#01)
                JR      NZ,CL_SET_2
                LD      A,B
                BIT     0,(IY+#02)
                JR      Z,CL_SET_1
                ADD     A,(IY+#31)
                SUB     #18
CL_SET_1:       PUSH    BC
                LD      B,A
                CALL    CL_ADDR
                POP     BC
CL_SET_2:       LD      A,#21
                SUB     C
                LD      E,A
                LD      D,#00
                ADD     HL,DE
                JP      PO_STORE

; Scroll part or whole display
CL_SC_ALL:      LD      B,#17
CL_SCROLL:      CALL    CL_ADDR
                LD      C,#08
CL_SCR_1:       PUSH    BC
                PUSH    HL
                LD      A,B
                AND     #07
                LD      A,B
                JR      NZ,CL_SCR_3
CL_SCR_2:       EX      DE,HL
                LD      HL,#F8E0
                ADD     HL,DE
                EX      DE,HL
                LD      BC,#0020
                DEC     A
                LDIR
CL_SCR_3:       EX      DE,HL
                LD      HL,#FFE0
                ADD     HL,DE
                EX      DE,HL
                LD      B,A
                AND     #07
                RRCA
                RRCA
                RRCA
                LD      C,A
                LD      A,B
                LD      B,#00
                LDIR
                LD      B,#07
                ADD     HL,BC
                AND     #F8
                JR      NZ,CL_SCR_2
                POP     HL
                INC     H
                POP     BC
                DEC     C
                JR      NZ,CL_SCR_1
                CALL    CL_ATTR
                LD      HL,#FFE0
                ADD     HL,DE
                EX      DE,HL
                LDIR
                LD      B,#01
CL_LINE:        PUSH    BC                      ; Clear text lines at the bottom of display
                CALL    CL_ADDR
                LD      C,#08
CL_LINE_1:      PUSH    BC
                PUSH    HL
                LD      A,B
CL_LINE_2:      AND     #07
                RRCA
                RRCA
                RRCA
                LD      C,A
                LD      A,B
                LD      B,#00
                DEC     C
                LD      D,H
                LD      E,L
                LD      (HL),#00
                INC     DE
                LDIR
                LD      DE,#0701
                ADD     HL,DE
                DEC     A
                AND     #F8
                LD      B,A
                JR      NZ,CL_LINE_2
                POP     HL
                INC     H
                POP     BC
                DEC     C
                JR      NZ,CL_LINE_1
                CALL    CL_ATTR
                LD      H,D
                LD      L,E
                INC     DE
                LD      A,(#5C8D)
                BIT     0,(IY+#02)
                JR      Z,CL_LINE_3
                LD      A,(#5C48)
CL_LINE_3:      LD      (HL),A
                DEC     BC
                LDIR
                POP     BC
                LD      C,#21
                RET

; Attribute handling
CL_ATTR:        LD      A,H
                RRCA
                RRCA
                RRCA
                DEC     A
                OR      #50
                LD      H,A
                EX      DE,HL
                LD      H,C
                LD      L,B
                ADD     HL,HL
                ADD     HL,HL
                ADD     HL,HL
                ADD     HL,HL
                ADD     HL,HL
                LD      B,H
                LD      C,L
                RET

; Handle display with line number
CL_ADDR:        LD      A,#18
                SUB     B
                LD      D,A
                RRCA
                RRCA
                RRCA
                AND     #E0
                LD      L,A
                LD      A,D
                AND     #18
                OR      #40
                LD      H,A
                RET

; Handle COPY command
COPY:           DI
                LD      B,#B0
                LD      HL,#4000
COPY_1:         PUSH    HL
                PUSH    BC
                CALL    COPY_LINE
                POP     BC
                POP     HL
                INC     H
                LD      A,H
                AND     #07
                JR      NZ,COPY_2
                LD      A,L
                ADD     A,#20
                LD      L,A
                CCF
                SBC     A,A
                AND     #F8
                ADD     A,H
                LD      H,A
COPY_2:         DJNZ    COPY_1
                JR      COPY_END

; Pass printer buffer to printer
COPY_BUFF:      DI
                LD      HL,#5B00
                LD      B,#08
COPY_3:         PUSH    BC
                CALL    COPY_LINE
                POP     BC
                DJNZ    COPY_3
COPY_END:       LD      A,#04
                OUT     (#FB),A
                EI
CLEAR_PRB:      LD      HL,#5B00                ; Clear printer buffer
                LD      (IY+#46),L
                XOR     A
                LD      B,A
PRB_BYTES:      LD      (HL),A
                INC     HL
                DJNZ    PRB_BYTES
                RES     1,(IY+#30)
                LD      C,#21
                JP      CL_SET

; Output 32 bytes (line) to the printer
COPY_LINE:      LD      A,B
                CP      #03
                SBC     A,A
                AND     #02
                OUT     (#FB),A
                LD      D,A
COPY_L_1:       CALL    BREAK_KEY
                JR      C,COPY_L_2
                LD      A,#04
                OUT     (#FB),A
                EI
                CALL    CLEAR_PRB
REPORT_DC:      RST     #08                     ; Error report
                DB      #0C                     ; BREAK - CONT repeats
COPY_L_2:       IN      A,(#FB)
                ADD     A,A
                RET     M
                JR      NC,COPY_L_1
                LD      C,#20
COPY_L_3:       LD      E,(HL)
                INC     HL
                LD      B,#08
COPY_L_4:       RL      D
                RL      E
                RR      D
COPY_L_5:       IN      A,(#FB)
                RRA
                JR      NC,COPY_L_5
                LD      A,D
                OUT     (#FB),A
                DJNZ    COPY_L_4
                DEC     C
                JR      NZ,COPY_L_3
                RET

; The editor routine - prepare or edit BASIC line, or handle INPUT expression
EDITOR:         LD      HL,(#5C3D)
                PUSH    HL
ED_AGAIN:       LD      HL,ED_ERROR
                PUSH    HL
                LD      (#5C3D),SP
ED_LOOP:        CALL    WAIT_KEY
                PUSH    AF
                LD      D,#00
                LD      E,(IY-#01)
                LD      HL,#00C8
                CALL    BEEPER
                POP     AF
                LD      HL,ED_LOOP
                PUSH    HL
                CP      #18
                JR      NC,ADD_CHAR
                CP      #07
                JR      C,ADD_CHAR
                CP      #10
                JR      C,ED_KEYS
                LD      BC,#0002
                LD      D,A
                CP      #16
                JR      C,ED_CONTR
                INC     BC
                BIT     7,(IY+#37)
                JP      Z,ED_IGNORE
                CALL    WAIT_KEY
                LD      E,A
ED_CONTR:       CALL    WAIT_KEY
                PUSH    DE
                LD      HL,(#5C5B)
                RES     0,(IY+#07)
                CALL    MAKE_ROOM
                POP     BC
                INC     HL
                LD      (HL),B
                INC     HL
                LD      (HL),C
                JR      ADD_CH_1

; Add code to current line
ADD_CHAR:       RES     0,(IY+#07)
                LD      HL,(#5C5B)
                CALL    ONE_SPACE
ADD_CH_1:       LD      (DE),A
                INC     DE
                LD      (#5C5B),DE
                RET

ED_KEYS:        LD      E,A
                LD      D,#00
                LD      HL,ED_KEYS_T-7
                ADD     HL,DE
                LD      E,(HL)
                ADD     HL,DE
                PUSH    HL
                LD      HL,(#5C5B)
                RET

; Editing keys table
ED_KEYS_T:      DB      #09                     ; ED_EDIT
                DB      #66                     ; ED_LEFT
                DB      #6A                     ; ED_RIGHT
                DB      #50                     ; ED_DOWN
                DB      #B5                     ; ED_UP
                DB      #70                     ; ED_DELETE
                DB      #7E                     ; ED_ENTER
                DB      #CF                     ; ED_SYMBOL
                DB      #D4                     ; ED_GRAPH

; Handle EDIT key
ED_EDIT:        LD      HL,(#5C49)
                BIT     5,(IY+#37)
                JP      NZ,CLEAR_SP
                CALL    LINE_ADDR
                CALL    LIN2                    ; BSROM - modified BASIC program presence test
                AND     #C0
                JP      NZ,CLEAR_SP
                PUSH    HL
                INC     HL
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                LD      HL,#000A
                ADD     HL,BC
                LD      B,H
                LD      C,L
                CALL    TEST_ROOM
                CALL    CLEAR_SP
                LD      HL,(#5C51)
                EX      (SP),HL
                PUSH    HL
                LD      A,#FF
                CALL    CHAN_OPEN
                POP     HL
                DEC     HL
                CALL    OUT_LINE                ;BSROM - cursor placement after EDIT
                LD      DE,#0005
                LD      HL,(#5C59)
                ADD     HL,DE
                LD      (#5C5B),HL
                POP     HL
                JP      CHAN_FLAG

TOERR:          LD      (#5C5F),HL              ; BSROM - cursor jumps to error
                LD      (#5C5B),HL
                RET

; Cursor down editing
ED_DOWN:        CALL    DOLE                    ; BSROM - free cursor moving
                BIT     5,(IY+#37)
                RET     NZ
                NOP
                CALL    LN_FETCH
                JR      ED_LIST

ED_STOP:        LD      (IY+#00),#10
                JR      ED_ENTER

; Cursor left editing
ED_LEFT:        CALL    ED_EDGE
                JR      ED_CUR

; Cursor right editing
ED_RIGHT:       LD      A,(HL)
                CP      #0D
                RET     Z
                INC     HL
ED_CUR:         LD      (#5C5B),HL
                RET

; Handling DELETE
ED_DELETE:      CALL    ED_EDGE
                LD      BC,#0001
                JP      RECLAIM_2

; Ignore next two codes from KEY_INPUT routine
ED_IGNORE:      CALL    WAIT_KEY
                CALL    WAIT_KEY
ED_ENTER:       POP     HL                      ; Handle ENTER
                POP     HL
ED_END:         POP     HL
                LD      (#5C3D),HL
                BIT     7,(IY+#00)
                RET     NZ
                LD      SP,HL
                RET

; Move cursor left when editing
ED_EDGE:        SCF
                CALL    SET_DE
                SBC     HL,DE
                ADD     HL,DE
                INC     HL
                POP     BC
                RET     C
                PUSH    BC
                LD      B,H
                LD      C,L
ED_EDGE_1:      LD      H,D
                LD      L,E
                INC     HL
                LD      A,(DE)
                AND     #F0
                CP      #10
                JR      NZ,ED_EDGE_2
                INC     HL
                LD      A,(DE)
                SUB     #17
                ADC     A,#00
                JR      NZ,ED_EDGE_2
                INC     HL
ED_EDGE_2:      AND     A
                SBC     HL,BC
                ADD     HL,BC
                EX      DE,HL
                JR      C,ED_EDGE_1
                RET

; Cursor up editing
ED_UP:          CALL    HORE                    ; BSROM - free cursor moving
                BIT     5,(IY+#37)
                RET     NZ
                CALL    LINE_ADDR
                EX      DE,HL
                CALL    LINE_NO
                LD      HL,#5C4A
                CALL    LN_STORE
ED_LIST:        CALL    AUTO_LIST
ED_LIST_1:      LD      A,#00
                JP      CHAN_OPEN

; Use of symbol and graphic codes
ED_SYMBOL:      BIT     7,(IY+#37)
                JR      Z,ED_ENTER
ED_GRAPH:       JP      ADD_CHAR

; Editor error handling
ED_ERROR:       BIT     4,(IY+#30)
                JR      Z,ED_END
                LD      (IY+#00),#FF
                LD      D,#00
                LD      E,(IY-#02)
                LD      HL,#0190                ; BSROM - higher tone of error beep, was LD HL,#1A90
                CALL    BEEPER
                JP      ED_AGAIN

; Clear workspace
CLEAR_SP:       PUSH    HL
                CALL    SET_HL
                DEC     HL
                CALL    RECLAIM_1
                LD      (#5C5B),HL
                LD      (IY+#07),#00
                POP     HL
                RET

; Handle keyboard input
KEY_INPUT:      BIT     3,(IY+#02)
                CALL    NZ,ED_COPY
                AND     A
                BIT     5,(IY+#01)
                RET     Z
                LD      A,(#5C08)
                RES     5,(IY+#01)
                PUSH    AF
                BIT     5,(IY+#02)
                CALL    NZ,CLS_LOWER
                POP     AF
                CP      #20
                JR      NC,KEY_DONE2
                CP      #10
                JR      NC,KEY_CONTR
                CP      #06
                JR      NC,KEY_M_CL
                LD      B,A
                AND     #01
                LD      C,A
                LD      A,B
                RRA
                ADD     A,#12
                JR      KEY_DATA

; Separate caps lock
KEY_M_CL:       JR      NZ,KEY_MODE
                LD      HL,#5C6A
                LD      A,#08
                XOR     (HL)
                LD      (HL),A
                JR      KEY_FLAG

; Mode handling
KEY_MODE:       CP      #0E
                RET     C
                SUB     #0D
                LD      HL,#5C41
                CP      (HL)
                LD      (HL),A
                JR      NZ,KEY_FLAG
                LD      (HL),#00
KEY_FLAG:       SET     3,(IY+#02)
                CP      A
                RET

; Handle colour controls
KEY_CONTR:      LD      B,A
                AND     #07
                LD      C,A
                LD      A,#10
                BIT     3,B
                JR      NZ,KEY_DATA
                INC     A
KEY_DATA:       LD      (IY-#2D),C
                LD      DE,KEY_NEXT
                JR      KEY_CHAN

KEY_NEXT:       LD      A,(#5C0D)
                LD      DE,KEY_INPUT
KEY_CHAN:       LD      HL,(#5C4F)
                INC     HL
                INC     HL
                LD      (HL),E
                INC     HL
                LD      (HL),D
KEY_DONE2:      SCF
                RET

; Print lower screen workspace
ED_COPY:        CALL    TEMPS
                RES     3,(IY+#02)
                RES     5,(IY+#02)
                LD      HL,(#5C8A)
                PUSH    HL
                LD      HL,(#5C3D)
                PUSH    HL
                LD      HL,ED_FULL
                PUSH    HL
                LD      (#5C3D),SP
                LD      HL,(#5C82)
                PUSH    HL
                SCF
                CALL    SET_DE
                EX      DE,HL
                CALL    OUT_LINE2
                EX      DE,HL
                CALL    OUT_CURS
                LD      HL,(#5C8A)
                EX      (SP),HL
                EX      DE,HL
                CALL    TEMPS
ED_BLANK:       LD      A,(#5C8B)
                SUB     D
                JR      C,ED_C_DONE
                JR      NZ,ED_SPACES
                LD      A,E
                SUB     (IY+#50)
                JR      NC,ED_C_DONE
ED_SPACES:      LD      A,#20
                PUSH    DE
                CALL    PRINT_OUT
                POP     DE
                JR      ED_BLANK

; Error handling
ED_FULL:        LD      D,#00
                LD      E,(IY-#02)
                LD      HL,#0190                ; BSROM - higher tone of error beep, was LD HL,#1A90
                CALL    BEEPER
                LD      (IY+#00),#FF
                LD      DE,(#5C8A)
                JR      ED_C_END

ED_C_DONE:      POP     DE
                POP     HL
ED_C_END:       POP     HL
                LD      (#5C3D),HL
                POP     BC
                PUSH    DE
                CALL    CL_SET
                POP     HL
                LD      (#5C82),HL
                LD      (IY+#26),#00
                RET

; Ensure that the proper pointers are selected for workspace
SET_HL:         LD      HL,(#5C61)
                DEC     HL
                AND     A
SET_DE:         LD      DE,(#5C59)
                BIT     5,(IY+#37)
                RET     Z
                LD      DE,(#5C61)
                RET     C
                LD      HL,(#5C63)
                RET

; Remove floating point from line
REMOVE_FP:      LD      A,(HL)
                CP      #0E
                LD      BC,#0006
                CALL    Z,RECLAIM_2
                LD      A,(HL)
                INC     HL
                CP      #0D
                JR      NZ,REMOVE_FP
                RET

; Handle NEW command
NEW:            DI
                LD      A,#FF
                LD      DE,(#5CB2)
NEW_1:          EXX
                LD      BC,(#5CB4)
                LD      DE,(#5C38)
                LD      HL,(#5C7B)
                EXX
START_NEW:      LD      B,A
                XOR     A                       ; BSROM - faster RAM clear, RAM is not tested for errors
                LD      I,A
                LD      C,A
                LD      H,D
                LD      L,E
                LD      A,B
                LD      B,C
                LD      SP,HL
CLSUJ:          PUSH    BC
                PUSH    BC
                PUSH    BC
                PUSH    BC
                PUSH    BC
                PUSH    BC
                PUSH    BC
                PUSH    BC
                LD      HL,#A7FF
                ADD     HL,SP
                JR      C,CLSUJ
                EX      DE,HL
                JR      RAM_DONE1

; Modified CONTINUE command
NEW_CONT:       CALL    FIND_INT2
                LD      A,B
                OR      C
                JP      Z,CONTINUE
                PUSH    BC
                RET
; Remains of original RAM_DONE routine
RAM_DONE1:      EXX
                LD      (#5CB4),BC
                LD      (#5C38),DE
                LD      (#5C7B),HL
                EXX    
                INC     A                       ; BSROM - changed for new NEW command, was INC B
                JR      Z,RAM_SET
RAM_DONE2:      LD      (#5CB4),HL
                LD      DE,#3EAF
                LD      BC,#00A8
                EX      DE,HL
                LDDR
                EX      DE,HL
                INC     HL
                LD      (#5C7B),HL
                DEC     HL
                LD      BC,#0040
                LD      (#5C38),BC
RAM_SET:        LD      (#5CB2),HL
                LD      HL,#3C00
                LD      (#5C36),HL
                LD      HL,(#5CB2)
                LD      (HL),#3E
                DEC     HL
                LD      SP,HL
                DEC     HL
                DEC     HL
                LD      (#5C3D),HL
                IM      1
                LD      IY,#5C3A
                EI
                LD      HL,#5CB6
                LD      (#5C4F),HL
                LD      DE,INIT_CHAN
                LD      BC,#0015
                EX      DE,HL
                LDIR
                EX      DE,HL
                DEC     HL
                LD      (#5C57),HL
                INC     HL
                LD      (#5C53),HL
                LD      (#5C4B),HL
                LD      (HL),#80
                INC     HL
                LD      (#5C59),HL
WARM_ST:        LD      (HL),#0D
                INC     HL
                LD      (HL),#80
                INC     HL
                LD      (#5C61),HL
                LD      (#5C63),HL
                LD      (#5C65),HL
                LD      A,#07                   ; BSROM - changed colors, blue border, black paper, white ink
                LD      (#5C8D),A
                LD      (#5C8F),A
                LD      (#5C48),A
                LD      HL,#0114                ; BSROM - REPDEL and REPPER were changed, was #0523
                LD      (#5C09),HL
                DEC     (IY-#3A)
                DEC     (IY-#36)
                LD      HL,INIT_STRM
                LD      DE,#5C10
                LD      BC,#000E
                LDIR
                LD      (IY+#31),#02            ; BSROM - printer vars initialization removed
                LD      (IY+#0E),#0F
                CALL    HARD                    ; reset AY, DMA, FDC
                CALL    SET_MIN
                LD      (IY+#00),#FF
                CALL    INFO                    ; copyright message replaced with status info
                CALL    SA_LD_RET
                JP      MAIN_4

; Main execution loop
MAIN_EXEC:      LD      (IY+#31),#02
                CALL    AUTO_LIST
MAIN_1:         CALL    SET_MIN
MAIN_2:         LD      A,#00
                CALL    CHAN_OPEN
                CALL    EDITOR
                CALL    LINE_SCAN
                BIT     7,(IY+#00)
                JR      NZ,MAIN_3
                BIT     4,(IY+#30)
                JR      Z,MAIN_4
                LD      HL,(#5C59)
                CALL    REMOVE_FP
                LD      (IY+#00),#FF
                JR      MAIN_2

MAIN_3:         LD      HL,(#5C59)
                LD      (#5C5D),HL
                CALL    LIN3                    ; BSROM - modified test of number at the begin of BASIC line
                NOP
                NOP
                JP      NC,MAIN_ADD             ; BSROM - don'
t test zero, so line 0 can be used and/or edited
                RST     #18
                CP      #0D
                JR      Z,MAIN_EXEC
                BIT     0,(IY+#30)
                CALL    NZ,CL_ALL
                CALL    CLS_LOWER
                LD      A,#19
                SUB     (IY+#4F)
                LD      (#5C8C),A
                SET     7,(IY+#01)
                LD      (IY+#00),#FF
                LD      (IY+#0A),#01
                CALL    LINE_RUN
MAIN_4:         RST     #38                     ; BSROM - bugfix - was HALT
                RES     5,(IY+#01)
                BIT     1,(IY+#30)
                CALL    NZ,COPY_BUFF
                LD      A,(#5C3A)
                INC     A
MAIN_G:         PUSH    AF
                LD      HL,#0000
                LD      (IY+#37),H
                LD      (IY+#26),H
                LD      (#5C0B),HL
                LD      HL,#0001
                LD      (#5C16),HL
                CALL    SET_MIN
                RES     5,(IY+#37)
                CALL    CLS_LOWER
                SET     5,(IY+#02)
                POP     AF
                LD      B,A
                CP      #0A
                JR      C,MAIN_5
                ADD     A,#07
MAIN_5:         CALL    OUT_CODE
                LD      A,#20
                RST     #10
                LD      A,B
                LD      DE,RPT_MESGS
                CALL    PO_MSG
                XOR     A
                LD      DE,COMMA_SP-1
                CALL    PO_MSG
                LD      BC,(#5C45)
                CALL    OUT_NUM_1
                LD      A,#3A
                RST     #10
                LD      C,(IY+#0D)
                LD      B,#00
                CALL    OUT_NUM_1
                CALL    CLEAR_SP
                LD      A,(#5C3A)
                INC     A
                JR      Z,MAIN_9
                CP      #09
                JR      Z,MAIN_6
                CP      #15
                JR      NZ,MAIN_7
MAIN_6:         INC     (IY+#0D)
MAIN_7:         LD      BC,#0003
                LD      DE,#5C70
                LD      HL,#5C44
                BIT     7,(HL)
                JR      Z,MAIN_8
                ADD     HL,BC
MAIN_8:         LDDR
MAIN_9:         LD      (IY+#0A),#FF
                RES     3,(IY+#01)
                JP      MAIN_2

;The error mesages, with last byte inverted.
;The first #80 entry is dummy entry.
RPT_MESGS:      DB      #80
                DC      "OK"
                DC      "NEXT without FOR"
                DC      "Variable not found"
                DC      "Subscript wrong"
                DC      "Out of memory"
                DC      "Out of screen"
                DC      "Number too big"
                DC      "RETURN without GOSUB"
                DC      "End of file"
                DC      "STOP statement"
                DC      "Invalid argument"
                DC      "Integer out of range"
                DC      "Nonsense in BASIC"
                DC      "BREAK - CONT repeats"
                DC      "Out of DATA"
                DC      "Invalid file name"
                DC      "No room for line"
                DC      "STOP in INPUT"
                DC      "FOR without NEXT"
                DC      "Invalid I/O device"
                DC      "Invalid colour"
                DC      "BREAK into program"
                DC      "RAMTOP no good"
                DC      "Statement lost"
                DC      "Invalid stream"
                DC      "FN without DEF"
                DC      "Parameter error"
                DC      "Tape loading error"
COMMA_SP:       DC      ", "

; BSROM - here was the copyright message in the original ZX Spectrum ROM.
COPYRIGHT:      DC      "Rom 140"
                DC      "Prog:"
                DB      #16
                DB      #00
                DB      #0B

                DC      "Vars:"
                DB      #16
                DB      #00
                DB      #16

                DC      "Free:"

; Out of memory handling
REPORT_G:       LD      A,#10
                LD      BC,#0000
                JP      MAIN_G

; Handle additon of BASIC line
MAIN_ADD:       LD      (#5C49),BC
                LD      HL,(#5C5D)
                EX      DE,HL
                LD      HL,REPORT_G
                PUSH    HL
                LD      HL,(#5C61)
                SCF
                SBC     HL,DE
                PUSH    HL
                LD      H,B
                LD      L,C
                CALL    LINE_ADDR
                JR      NZ,MAIN_ADD1
                CALL    NEXT_ONE
                CALL    RECLAIM_2
MAIN_ADD1:      POP     BC
                LD      A,C
                DEC     A
                OR      B
                JR      Z,MAIN_ADD2
                PUSH    BC
                INC     BC
                INC     BC
                INC     BC
                INC     BC
                DEC     HL
                LD      DE,(#5C53)
                PUSH    DE
                CALL    MAKE_ROOM
                POP     HL
                LD      (#5C53),HL
                POP     BC
                PUSH    BC
                INC     DE
                LD      HL,(#5C61)
                DEC     HL
                DEC     HL
                LDDR
                LD      HL,(#5C49)
                EX      DE,HL
                POP     BC
                LD      (HL),B
                DEC     HL
                LD      (HL),C
                DEC     HL
                LD      (HL),E
                DEC     HL
                LD      (HL),D
MAIN_ADD2:      POP     AF
                JP      MAIN_EXEC

; Initial channel information
INIT_CHAN:      DW      PRINT_OUT
                DW      KEY_INPUT
                DB      "K"
                DW      PRINT_OUT
                DW      REPORT_J
                DB      "S"
                DW      ADD_CHAR
                DW      REPORT_J
                DB      "R"
                DW      PRINT_OUT
                DW      REPORT_J
                DB      "P"
                DB      #80                     ; End marker

REPORT_J:       RST     #08                     ; Error report
                DB      #12                     ; Invalid I/O device

; Initial stream data
INIT_STRM:      DB      #01, #00                ; stream #FD offset to channel 'K'
                DB      #06, #00                ; stream #FE offset to channel 'S'
                DB      #0B, #00                ; stream #FF offset to channel 'R'
                DB      #01, #00                ; stream #00 offset to channel 'K'
                DB      #01, #00                ; stream #01 offset to channel 'K'
                DB      #06, #00                ; stream #02 offset to channel 'S'
                DB      #10, #00                ; stream #03 offset to channel 'P'

; Control for input subroutine
WAIT_KEY:       BIT     5,(IY+#02)
                JR      NZ,WAIT_KEY1
                SET     3,(IY+#02)
WAIT_KEY1:      CALL    INPUT_AD
                RET     C
                JR      Z,WAIT_KEY1
REPORT_8:       RST     #08                     ; Error report
                DB      #07                     ; End of file
INPUT_AD:       EXX
                PUSH    HL
                LD      HL,(#5C51)
                INC     HL
                INC     HL
                JR      CALL_SUB

; Print ascii equivalent of a value 0-9
OUT_CODE:       LD      E,#30
                ADD     A,E
PRINT_A_2:      EXX
                PUSH    HL
                LD      HL,(#5C51)
CALL_SUB:       LD      E,(HL)
                INC     HL
                LD      D,(HL)
                EX      DE,HL
                CALL    CALL_JUMP
                POP     HL
                EXX
                RET

; Open a channel 'K', 'S', 'R' or 'P'
CHAN_OPEN:      ADD     A,A
                ADD     A,#16
                LD      L,A
                LD      H,#5C
                LD      E,(HL)
                INC     HL
                LD      D,(HL)
                LD      A,D
                OR      E
                JR      NZ,CHAN_OP_1
REPORT_OA:      RST     #08                     ; Error report
                DB      #17                     ; Invalid stream
CHAN_OP_1:      DEC     DE
                LD      HL,(#5C4F)
                ADD     HL,DE
CHAN_FLAG:      LD      (#5C51),HL              ; Set channel flags
                RES     4,(IY+#30)
                INC     HL
                INC     HL
                INC     HL
                INC     HL
                LD      C,(HL)
                LD      HL,CH_CD_LU
                CALL    INDEXER
                RET     NC
                LD      D,#00
                LD      E,(HL)
                ADD     HL,DE
CALL_JUMP:      JP      (HL)

; Channel code lookup table
CH_CD_LU:       DB      "K", #06                ; CHAN_K
                DB      "S", #12                ; CHAN_S
                DB      "P", #1B                ; CHAN_P
                DB      #00                     ; End marker

; Channel K flag
CHAN_K:         SET     0,(IY+#02)
                RES     5,(IY+#01)
                SET     4,(IY+#30)
                JR      CHAN_S_1

; Channel S flag
CHAN_S:         RES     0,(IY+#02)
CHAN_S_1:       RES     1,(IY+#01)
                JP      TEMPS

; Channel P flag
CHAN_P:         SET     1,(IY+#01)
                RET

; Create a single space in workspace by ADD_CHAR
ONE_SPACE:      LD      BC,#0001
MAKE_ROOM:      PUSH    HL              ; Create BC spaces in various areas
                CALL    TEST_ROOM
                POP     HL
                CALL    POINTERS
                LD      HL,(#5C65)
                EX      DE,HL
                LDDR
                RET

; Adjust pointers before making or reclaiming room
POINTERS:       PUSH    AF
                PUSH    HL
                LD      HL,#5C4B
                LD      A,#0E
PTR_NEXT:       LD      E,(HL)
                INC     HL
                LD      D,(HL)
                EX      (SP),HL
                AND     A
                SBC     HL,DE
                ADD     HL,DE
                EX      (SP),HL
                JR      NC,PTR_DONE
                PUSH    DE
                EX      DE,HL
                ADD     HL,BC
                EX      DE,HL
                LD      (HL),D
                DEC     HL
                LD      (HL),E
                INC     HL
                POP     DE
PTR_DONE:       INC     HL
                DEC     A
                JR      NZ,PTR_NEXT
                EX      DE,HL
                POP     DE
                POP     AF
                AND     A
                SBC     HL,DE
                LD      B,H
                LD      C,L
                INC     BC
                ADD     HL,DE
                EX      DE,HL
                RET

; Collect line number
LINE_ZERO:      DB      #00, #00                ; Dummy line number for direct commands

LINE_NO_A:      EX      DE,HL
                LD      DE,LINE_ZERO
LINE_NO:        LD      A,(HL)
                AND     #C0
                JR      NZ,LINE_NO_A
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                RET

; Handle reserve room, continuation of the restart BC_SPACES
RESERVE:        LD      HL,(#5C63)
                DEC     HL
                CALL    MAKE_ROOM
                INC     HL
                INC     HL
                POP     BC
                LD      (#5C61),BC
                POP     BC
                EX      DE,HL
                INC     HL
                RET

; Clear editing areas
SET_MIN:        LD      HL,(#5C59)
                LD      (HL),#0D
                LD      (#5C5B),HL
                INC     HL
                LD      (HL),#80
                INC     HL
                LD      (#5C61),HL
SET_WORK:       LD      HL,(#5C61)
                LD      (#5C63),HL
SET_STK:        LD      HL,(#5C63)
                LD      (#5C65),HL
                PUSH    HL
                LD      HL,#5C92
                LD      (#5C68),HL
                POP     HL
                RET

; Not used code, remains of ZX80/ZX81 legacy code
REC_EDIT:       LD      DE,(#5C59)
                JP      RECLAIM_1

; Table indexing routine
INDEXER_1:      INC     HL
INDEXER:        LD      A,(HL)
                AND     A
                RET     Z
                CP      C
                INC     HL
                JR      NZ,INDEXER_1
                SCF
                RET

; Handle CLOSE# command
CLOSE:          CALL    STR_DATA
                CALL    CLOSE_2
                LD      BC,#0000
                LD      DE,#A3E2
                EX      DE,HL
                ADD     HL,DE
                JR      C,CLOSE_1
                LD      BC,INIT_STRM+14
                ADD     HL,BC
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
CLOSE_1:        EX      DE,HL
                LD      (HL),C
                INC     HL
                LD      (HL),B
                RET

CLOSE_2:        PUSH    HL
                LD      HL,(#5C4F)
                ADD     HL,BC
                INC     HL
                INC     HL
                INC     HL
                LD      C,(HL)
                EX      DE,HL
                LD      HL,CL_STR_LU
                CALL    INDEXER
                LD      C,(HL)
                LD      B,#00
                ADD     HL,BC
                JP      (HL)

; Close stream lookup table
CL_STR_LU:      DB      "K", #05
                DB      "S", #03
                DB      "P", #01

CLOSE_STR:      POP     HL
                RET

; Stream data
STR_DATA:       CALL    FIND_INT1
                CP      #10
                JR      C,STR_DATA1
REPORT_OB:      RST     #08                     ; Error report
                DB      #17                     ; Invalid stream
STR_DATA1:      ADD     A,#03
                RLCA
                LD      HL,#5C10
                LD      C,A
                LD      B,#00
                ADD     HL,BC
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                DEC     HL
                RET

; Handle OPEN# command
OPEN:           RST     #28                     ;FP_CALC
                DB      #01                     ;EXCHANGE
                DB      #38                     ;END_CALC
                CALL    STR_DATA
                LD      A,B
                OR      C
                JR      Z,OPEN_1
                EX      DE,HL
                LD      HL,(#5C4F)
                ADD     HL,BC
                INC     HL
                INC     HL
                INC     HL
                LD      A,(HL)
                EX      DE,HL
                CP      #4B
                JR      Z,OPEN_1
                CP      #53
                JR      Z,OPEN_1
                CP      #50
                JR      NZ,REPORT_OB
OPEN_1:         CALL    OPEN_2
                LD      (HL),E
                INC     HL
                LD      (HL),D
                RET

OPEN_2:         PUSH    HL
                CALL    STK_FETCH
                LD      A,B
                OR      C
                JR      NZ,OPEN_3
REPORT_F:       RST     #08                     ; Error report
                DB      #0E                     ; Invalid file name
OPEN_3:         PUSH    BC
                LD      A,(DE)
                AND     #DF
                LD      C,A
                LD      HL,OP_STR_LU
                CALL    INDEXER
                JR      NC,REPORT_F
                LD      C,(HL)
                LD      B,#00
                ADD     HL,BC
                POP     BC
                JP      (HL)

; Open stream lookup table
OP_STR_LU:      DB      "K", #06                ; OPEN_K
                DB      "S", #08                ; OPEN_S
                DB      "P", #0A                ; OPEN_P
                DB      #00                     ; End marker

; Open keyboard stream
OPEN_K:         LD      E,#01
                JR      OPEN_END

; Open Screen stream
OPEN_S:         LD      E,#06
                JR      OPEN_END

; Open printer stream
OPEN_P:         LD      E,#10
OPEN_END:       DEC     BC
                LD      A,B
                OR      C
                JR      NZ,REPORT_F
                LD      D,A
                POP     HL
                RET

; Handle CAT, ERASE, FORMAT and MOVE commands
CAT_ETC:        JR      REPORT_OB

; Automatic listing in the upper screen
AUTO_LIST:      LD      (#5C3F),SP
                LD      (IY+#02),#10
                CALL    CL_ALL
                SET     0,(IY+#02)
                LD      B,(IY+#31)
                CALL    CL_LINE
                RES     0,(IY+#02)
                SET     0,(IY+#30)
                LD      HL,(#5C49)
                LD      DE,(#5C6C)
                AND     A
                SBC     HL,DE
                ADD     HL,DE
                JR      C,AUTO_L_2
                PUSH    DE
                CALL    LINE_ADDR
                LD      DE,#02C0
                EX      DE,HL
                SBC     HL,DE
                EX      (SP),HL
                CALL    LINE_ADDR
                POP     BC
AUTO_L_1:       PUSH    BC
                CALL    NEXT_ONE
                POP     BC
                ADD     HL,BC
                JR      C,AUTO_L_3
                EX      DE,HL
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                DEC     HL
                LD      (#5C6C),DE
                JR      AUTO_L_1

AUTO_L_2:       LD      (#5C6C),HL
AUTO_L_3:       LD      HL,(#5C6C)
                CALL    LINE_ADDR
                JR      Z,AUTO_L_4
                EX      DE,HL
AUTO_L_4:       CALL    LIST_ALL
                RES     4,(IY+#02)
                RET

; Handle LLIST command
LLIST:          LD      A,#03
                JR      LIST_1

; Handle LIST command
LIST:           LD      A,#02
LIST_1:         LD      (IY+#02),#00
                CALL    SYNTAX_Z
                CALL    NZ,CHAN_OPEN
                RST     #18
                CALL    STR_ALTER
                JR      C,LIST_4
                RST     #18
                CP      #3B
                JR      Z,LIST_2
                CP      #2C
                JR      NZ,LIST_3
LIST_2:         RST     #20
                CALL    EXPT_1NUM
                JR      LIST_5

LIST_3:         CALL    USE_ZERO
                JR      LIST_5

LIST_4:         CALL    FETCH_NUM
LIST_5:         CALL    CHECK_END
                CALL    FIND_INT2
                LD      A,B
                AND     #3F
                LD      H,A
                LD      L,C
                LD      (#5C49),HL
                CALL    LINE_ADDR
LIST_ALL:       LD      E,#01
LIST_ALL_2:     CALL    OUT_LINE
                RST     #10
                BIT     4,(IY+#02)
                JR      Z,LIST_ALL_2
                LD      A,(#5C6B)
                SUB     (IY+#4F)
                JR      NZ,LIST_ALL_2
                XOR     E
                RET     Z
                PUSH    HL
                PUSH    DE
                LD      HL,#5C6C
                CALL    LN_FETCH
                POP     DE
                POP     HL
                JR      LIST_ALL_2

; Print a whole BASIC line
OUT_LINE:       LD      BC,(#5C49)
                CALL    CP_LINES
                LD      D,#2A                   ; BSROM - line cursor is "*" instead of ">"
                JR      Z,OUT_LINE1
                LD      DE,#2000                ; BSROM - " " instead of suppressing line cursor
                RL      E
OUT_LINE1:      LD      (IY+#2D),E
                LD      A,(HL)
                CP      #40
                POP     BC
                RET     NC
                PUSH    BC
                CALL    LIN4                    ; BSROM - no cursor
                INC     HL
                INC     HL
                INC     HL
                XOR     A
                XOR     D
                JR      Z,OUT_LINE1A
                RST     #10
OUT_LINE1A:     NOP                             ; remains of old code are replaced with NOPs
                NOP
                NOP
                NOP
OUT_LINE2:      SET     0,(IY+#01)
OUT_LINE3:      PUSH    DE
                EX      DE,HL
                RES     2,(IY+#30)
                LD      HL,#5C3B
                RES     2,(HL)
                BIT     5,(IY+#37)
                JR      Z,OUT_LINE4
                SET     2,(HL)
OUT_LINE4:      LD      HL,(#5C5F)
                AND     A
                SBC     HL,DE
                JR      NZ,OUT_LINE5
                LD      A,#3F
                CALL    OUT_FLASH
OUT_LINE5:      CALL    OUT_CURS
                EX      DE,HL
                LD      A,(HL)
                CALL    NUMBER
                INC     HL
                CP      #0D
                JR      Z,OUT_LINE6
                EX      DE,HL
                CALL    OUT_CHAR
                JR      OUT_LINE4

OUT_LINE6:      POP     DE
                RET

; Check for a number marker
NUMBER:         CP      #0E
                RET     NZ
                INC     HL
                INC     HL
                INC     HL
                INC     HL
                INC     HL
                INC     HL
                LD      A,(HL)
                RET

; Print a flashing character
OUT_FLASH:      EXX
                LD      HL,(#5C8F)
                PUSH    HL
                RES     7,H
                SET     7,L
                LD      (#5C8F),HL
                LD      HL,#5C91
                LD      D,(HL)
                PUSH    DE
                LD      (HL),#00
                CALL    PRINT_OUT
                POP     HL
                LD      (IY+#57),H
                POP     HL
                LD      (#5C8F),HL
                EXX
                RET

; Print the cursor
OUT_CURS:       LD      HL,(#5C5B)
                AND     A
                SBC     HL,DE
                RET     NZ
                LD      A,(#5C41)
                RLC     A
                JR      Z,OUT_C_1
                ADD     A,#43
                JR      OUT_C_2

OUT_C_1:        LD      HL,#5C3B
                RES     3,(HL)
                LD      A,#4B
                BIT     2,(HL)
                JR      Z,OUT_C_2
                SET     3,(HL)
                INC     A
                BIT     3,(IY+#30)
                JR      Z,OUT_C_2
                LD      A,#43
OUT_C_2:        PUSH    DE
                CALL    OUT_FLASH
                POP     DE
                RET

; Get line number of the next line
LN_FETCH:       LD      E,(HL)
                INC     HL
                LD      D,(HL)
                PUSH    HL
                EX      DE,HL
                INC     HL
                CALL    LINE_ADDR
                CALL    LINE_NO
                POP     HL
LN_STORE:       BIT     5,(IY+#37)
                RET     NZ
                LD      (HL),D
                DEC     HL
                LD      (HL),E
                RET

; Outputting numbers at start of BASIC line
OUT_SP_2:       LD      A,E
                AND     A
                RET     M
                JR      OUT_CHAR

OUT_SP_NO:      XOR     A
OUT_SP_1:       ADD     HL,BC
                INC     A
                JR      C,OUT_SP_1
                SBC     HL,BC
                DEC     A
                JR      Z,OUT_SP_2
                JP      OUT_CODE

; Outputting characters in a BASIC line
OUT_CHAR:       CALL    NUMERIC
                JR      NC,OUT_CH_3
                CP      #21
                JR      C,OUT_CH_3
                RES     2,(IY+#01)
                CP      #CB
                JR      Z,OUT_CH_3
                CP      #3A
                JR      NZ,OUT_CH_1
                BIT     5,(IY+#37)
                JR      NZ,OUT_CH_2
                BIT     2,(IY+#30)
                JR      Z,OUT_CH_3
                JR      OUT_CH_2

OUT_CH_1:       CP      #22
                JR      NZ,OUT_CH_2
                PUSH    AF
                LD      A,(#5C6A)
                XOR     #04
                LD      (#5C6A),A
                POP     AF
OUT_CH_2:       SET     2,(IY+#01)
OUT_CH_3:       RST     #10
                RET

; Get starting address of line (or line after)
LINE_ADDR:      PUSH    HL
                LD      HL,(#5C53)
                LD      D,H
                LD      E,L
LINE_AD_1:      POP     BC
                CALL    LIN1                    ; BSROM - modified line number test
                RET     NC
                PUSH    BC
                CALL    NEXT_ONE
                EX      DE,HL
                JR      LINE_AD_1

; Compare line numbers
CP_LINES:       LD      A,(HL)
                CP      B
                RET     NZ
                INC     HL
                LD      A,(HL)
                DEC     HL
                CP      C
                RET

; Find each statement
                INC     HL                      ; 3x INC HL not used in this ROM
                INC     HL
                INC     HL
EACH_STMT:      LD      (#5C5D),HL
                LD      C,#00
EACH_S_1:       DEC     D
                RET     Z
                RST     #20
                CP      E
                JR      NZ,EACH_S_3
                AND     A
                RET

EACH_S_2:       INC     HL
                LD      A,(HL)
EACH_S_3:       CALL    NUMBER
                LD      (#5C5D),HL
                CP      #22
                JR      NZ,EACH_S_4
                DEC     C
EACH_S_4:       CP      #3A
                JR      Z,EACH_S_5
                CP      #CB
                JR      NZ,EACH_S_6
EACH_S_5:       BIT     0,C
                JR      Z,EACH_S_1
EACH_S_6:       CP      #0D
                JR      NZ,EACH_S_2
                DEC     D
                SCF
                RET

; Find the address of the next line in the program area,
; or the next variable in the variables area
NEXT_ONE:       PUSH    HL
                LD      A,(HL)
                CP      #40
                JR      C,NEXT_O_3
                BIT     5,A
                JR      Z,NEXT_O_4
                ADD     A,A
                JP      M,NEXT_O_1
                CCF
NEXT_O_1:       LD      BC,#0005
                JR      NC,NEXT_O_2
                LD      C,#12
NEXT_O_2:       RLA
                INC     HL
                LD      A,(HL)
                JR      NC,NEXT_O_2
                JR      NEXT_O_5

NEXT_O_3:       INC     HL
NEXT_O_4:       INC     HL
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                INC     HL
NEXT_O_5:       ADD     HL,BC
                POP     DE
DIFFER:         AND     A
                SBC     HL,DE
                LD      B,H
                LD      C,L
                ADD     HL,DE
                EX      DE,HL
                RET

; Handle reclaiming space
RECLAIM_1:      CALL    DIFFER
RECLAIM_2:      PUSH    BC
                LD      A,B
                CPL
                LD      B,A
                LD      A,C
                CPL
                LD      C,A
                INC     BC
                CALL    POINTERS
                EX      DE,HL
                POP     HL
                ADD     HL,DE
                PUSH    DE
                LDIR
                POP     HL
                RET
               
; Read line number of line editing area
E_LINE_NO:      LD      HL,(#5C59)
                DEC     HL
                LD      (#5C5D),HL
                RST     #20
                LD      HL,#5C92
                LD      (#5C65),HL
                CALL    INT_TO_FP
                CALL    FP_TO_BC
                JR      C,E_L_1
                LD      HL,#C000                ; BSROM - line number can be 0..16383 now, was LD HL,$D8F0 (max 9999 lines)
                ADD     HL,BC
E_L_1:          JP      C,REPORT_C
                JP      SET_STK

; Report and line number outputting
OUT_NUM_1:      PUSH    DE
                PUSH    HL
                XOR     A
                BIT     7,B
                JR      NZ,OUT_NUM_4
                LD      H,B
                LD      E,#FF                   ;BSROM - lines 0..16383
                JP      NUMCOM

OUT_NUM_2:      PUSH    DE
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                PUSH    HL
                EX      DE,HL
                LD      E,#20
OUT_NUM_3:      LD      BC,#FC18
                CALL    OUT_SP_NO
                LD      BC,#FF9C
                CALL    OUT_SP_NO
                LD      C,#F6
                CALL    OUT_SP_NO
                LD      A,L
OUT_NUM_4:      CALL    OUT_CODE
                POP     HL
                POP     DE
                RET

; The offset table for command interpretation
OFFST_TBL:      DB      #B1                     ; P_DEF_FN
                DB      #CB                     ; P_CAT
                DB      #BC                     ; P_FORMAT
                DB      #BF                     ; P_MOVE
                DB      #C4                     ; P_ERASE
                DB      #AF                     ; P_OPEN
                DB      #B4                     ; P_CLOSE
                DB      #93                     ; P_MERGE
                DB      #91                     ; P_VERIFY
                DB      #92                     ; P_BEEP
                DB      #95                     ; P_CIRCLE
                DB      #98                     ; P_INK
                DB      #98                     ; P_PAPER
                DB      #98                     ; P_FLASH
                DB      #98                     ; P_BRIGHT
                DB      #98                     ; P_INVERSE
                DB      #98                     ; P_OVER
                DB      #98                     ; P_OUT
                DB      #7F                     ; P_LPRINT
                DB      #81                     ; P_LLIST
                DB      #2E                     ; P_STOP
                DB      #6C                     ; P_READ
                DB      #6E                     ; P_DATA
                DB      #70                     ; P_RESTORE
                DB      #48                     ; P_NEW
                DB      #94                     ; P_BORDER
                DB      #56                     ; P_CONT
                DB      #3F                     ; P_DIM
                DB      #41                     ; P_REM
                DB      #2B                     ; P_FOR
                DB      #17                     ; P_GO_TO
                DB      #1F                     ; P_GO_SUB
                DB      #37                     ; P_INPUT
                DB      #77                     ; P_LOAD
                DB      #44                     ; P_LIST
                DB      #0F                     ; P_LET
                DB      #59                     ; P_PAUSE
                DB      #2B                     ; P_NEXT
                DB      #43                     ; P_POKE
                DB      #2D                     ; P_PRINT
                DB      #51                     ; P_PLOT
                DB      #3A                     ; P_RUN
                DB      #6D                     ; P_SAVE
                DB      #42                     ; P_RANDOM
                DB      #0D                     ; P_IF
                DB      #49                     ; P_CLS
                DB      #5C                     ; P_DRAW
                DB      #44                     ; P_CLEAR
                DB      #15                     ; P_RETURN
                DB      #5D                     ; P_COPY

; The parameter table. List of parameters for commands.        
P_LET:          DB      #01
                DB      "="
                DB      #02

P_GO_TO:        DB      #03                     ; BSROM - enhanced GOTO command, parameter is optional
                DW      GO_TO
                DB      #00

P_IF:           DB      #06
                DB      #CB
                DB      #05
                DW      IF_CMD

P_GO_SUB:       DB      #03                     ; BSROM - enhanced GOSUB command, parameter is optional
                DW      GO_SUB
                DB      #00
       
P_STOP:         DB      #00
                DW      STOP

P_RETURN:       DB      #00
                DW      RETURN

P_FOR:          DB      #04
                DB      "="
                DB      #06
                DB      #CC
                DB      #06
                DB      #05
                DW      FOR

P_NEXT:         DB      #04
                DB      #00
                DW      NEXT

P_PRINT:        DB      #05
                DW      PRINT

P_INPUT:        DB      #05
                DW      INPUT

P_DIM:          DB      #05
                DW      DIM

P_REM:          DB      #05
                DW      REM

P_NEW:          DB      #00
                DW      NEW

P_RUN:          DB      #03
                DW      RUN

P_LIST:         DB      #05
                DW      LIST

P_POKE:         DB      #06                     ; BSROM - enhanced POKE comand, added more items
                DB      #05
                DW      NEW_POKE

P_RANDOM:       DB      #03
                DW      RANDOMIZE

P_CONT:         DB      #03                     ; BSROM - enhanced CONTINUE command, added numeric parameter
                DW      NEW_CONT
       
P_CLEAR:        DB      #03
                DW      CLEAR

P_CLS:          DB      #03                     ; BSROM - enhanced CLS command, added numeric parameter
                DW      NEW_CLS

P_PLOT:         DB      #09
                DB      #00
                DW      PLOT

P_PAUSE:        DB      #03                     ; BSROM - enhanced PAUSE command, parameter is optional
                DW      PAUSE
                DB      #00

P_READ:         DB      #05
                DW      READ

P_DATA:         DB      #05
                DW      DATA

P_RESTORE:      DB      #03
                DW      RESTORE

P_DRAW:         DB      #09
                DB      #05
                DW      DRAW

P_COPY:         DB      #00
                DW      COPY

P_LPRINT:       DB      #05
                DW      LPRINT

P_LLIST:        DB      #05
                DW      LLIST

P_SAVE:         DB      #0B
P_LOAD:         DB      #0B
P_VERIFY:       DB      #0B
P_MERGE:        DB      #0B

P_BEEP:         DB      #08
                DB      #00
                DW      BEEP

P_CIRCLE:       DB      #09
                DB      #05
                DW      CIRCLE

P_INK:          DB      #07
P_PAPER:        DB      #07
P_FLASH:        DB      #07
P_BRIGHT:       DB      #07
P_INVERSE:      DB      #07
P_OVER:         DB      #07

P_OUT:          DB      #08
                DB      #00
                DW      OUT_CMD

P_BORDER:       DB      #03                     ; BSROM - enhanced BORDER command, parameter s optional
                DW      BORDER
                DB      #00
       
P_DEF_FN:       DB      #05
                DW      DEF_FN

P_OPEN:         DB      #06
                DB      ","
                DB      #0A
                DB      #00
                DW      OPEN

P_CLOSE:        DB      #06
                DB      #00
                DW      CLOSE

P_FORMAT:       DB      #0A
                DB      #00
                DW      CAT_ETC

P_MOVE:         DB      #0A
                DB      ","
                DB      #0A
                DB      #00
                DW      CAT_ETC

P_ERASE:        DB      #0A
                DB      #00
                DW      CAT_ETC

P_CAT:          DB      #00
                DW      CAT_ETC

; Main parser of BASIC interpreter
LINE_SCAN:      RES     7,(IY+#01)
                CALL    E_LINE_NO
                XOR     A
                LD      (#5C47),A
                DEC     A
                LD      (#5C3A),A
                JR      STMT_L_1

; Statement loop
STMT_LOOP:      RST     #20
STMT_L_1:       CALL    SET_WORK
                INC     (IY+#0D)
                JP      M,REPORT_C
                RST     #18
                LD      B,#00
                CP      #0D
                JR      Z,LINE_END
                CP      #3A
                JR      Z,STMT_LOOP
                LD      HL,STMT_RET
                PUSH    HL
                CP      #CE                     ;BSROM - automatic print
                JP      C,COMM
                SUB     #CE
                LD      C,A
                RST     #20
                LD      HL,OFFST_TBL
                ADD     HL,BC
                LD      C,(HL)
                ADD     HL,BC
                JR      GET_PARAM

; The main scanning loop
SCAN_LOOP:      LD      HL,(#5C74)
GET_PARAM:      LD      A,(HL)
                INC     HL
                LD      (#5C74),HL
                LD      BC,SCAN_LOOP
                PUSH    BC
                LD      C,A
                CP      #20
                JR      NC,SEPARATOR
                LD      HL,CLASS_TBL
                LD      B,#00
                ADD     HL,BC
                LD      C,(HL)
                ADD     HL,BC
                PUSH    HL
                RST     #18
                DEC     B
                RET

; Verify that the mandatory separator is present in correct location
SEPARATOR:      RST     #18
                CP      C
                JP      NZ,REPORT_C
                RST     #20
                RET

; Handle BREAK, return, and direct commands
STMT_RET:       CALL    BREAK_KEY
                JR      C,STMT_R_1
REPORT_L:       RST     #08                     ; Error report
                DB      #14                     ; BREAK into program
STMT_R_1:       BIT     7,(IY+#0A)
                JR      NZ,STMT_NEXT
                LD      HL,(#5C42)
                BIT     7,H
                JR      Z,LINE_NEW
LINE_RUN:       LD      HL,#FFFE
                LD      (#5C45),HL
                LD      HL,(#5C61)
                DEC     HL
                LD      DE,(#5C59)
                DEC     DE
                LD      A,(#5C44)
                JR      NEXT_LINE

; Find start address of a new line
LINE_NEW:       CALL    LINE_ADDR
                LD      A,(#5C44)
                JR      Z,LINE_USE
                AND     A
                JR      NZ,REPORT_N
                LD      B,A
                LD      A,(HL)
                AND     #C0
                LD      A,B
                JR      Z,LINE_USE
REPORT_0:       RST     #08                     ; Error report
                DB      #FF                     ; OK

; REM command
REM:            POP     BC

; End of line test
LINE_END:       CALL    SYNTAX_Z
                RET     Z
                LD      HL,(#5C55)
                LD      A,#C0
                AND     (HL)
                RET     NZ
                XOR     A
LINE_USE:       CP      #01                     ; General line checking
                ADC     A,#00
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                LD      (#5C45),DE
                INC     HL
                LD      E,(HL)
                INC     HL
                LD      D,(HL)
                EX      DE,HL
                ADD     HL,DE
                INC     HL
NEXT_LINE:      LD      (#5C55),HL
                EX      DE,HL
                LD      (#5C5D),HL
                LD      D,A
                LD      E,#00
                LD      (IY+#0A),#FF
                DEC     D
                LD      (IY+#0D),D
                JP      Z,STMT_LOOP
                INC     D
                CALL    EACH_STMT
                JR      Z,STMT_NEXT
REPORT_N:       RST     #08                     ; Error report
                DB      #16                     ; Statement lost

; End of statements
CHECK_END:      CALL    SYNTAX_Z
                RET     NZ
                POP     BC
                POP     BC
STMT_NEXT:      RST     #18                     ; Go to next statement
                CP      #0D
                JR      Z,LINE_END
                CP      #3A
                JP      Z,STMT_LOOP
                JP      REPORT_C

; Command class table
CLASS_TBL:      DB      #0F                     ; CLASS_00
                DB      #1D                     ; CLASS_01
                DB      #4B                     ; CLASS_02
                DB      #09                     ; CLASS_03
                DB      #67                     ; CLASS_04
                DB      #0B                     ; CLASS_05
                DB      #7B                     ; CLASS_06
                DB      #8E                     ; CLASS_07
                DB      #71                     ; CLASS_08
                DB      #B4                     ; CLASS_09
                DB      #81                     ; CLASS_0A
                DB      #CF                     ; CLASS_0B

; Command classes 00 - no operand, 03 - optional operand, 05 - variable syntax checked by routine
CLASS_03:       CALL    FETCH_NUM
CLASS_00:       CP      A
CLASS_05:       POP     BC
                CALL    Z,CHECK_END
                EX      DE,HL
                LD      HL,(#5C74)
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                EX      DE,HL
                PUSH    BC
                RET

; Command classes
; 01 - variable is required
; 02 - expression is required
; 04 - single character variable is required
CLASS_01:       CALL    LOOK_VARS
VAR_A_1:        LD      (IY+#37),#00
                JR      NC,VAR_A_2
                SET     1,(IY+#37)
                JR      NZ,VAR_A_3
REPORT_2:       RST     #08                     ; Error report
                DB      #01                     ; Variable not found;
VAR_A_2:        CALL    Z,STK_VAR
                BIT     6,(IY+#01)
                JR      NZ,VAR_A_3
                XOR     A
                CALL    SYNTAX_Z
                CALL    NZ,STK_FETCH
                LD      HL,#5C71
                OR      (HL)
                LD      (HL),A
                EX      DE,HL
VAR_A_3:        LD      (#5C72),BC
                LD      (#5C4D),HL
                RET

CLASS_02:       POP     BC
                CALL    VAL_FET_1
                CALL    CHECK_END
                RET

; Fetch a value
VAL_FET_1:      LD      A,(#5C3B)
VAL_FET_2:      PUSH    AF
                CALL    SCANNING
                POP     AF
                LD      D,(IY+#01)
                XOR     D
                AND     #40
                JR      NZ,REPORT_C
                BIT     7,D
                JP      NZ,LET
                RET

CLASS_04:       CALL    LOOK_VARS
                PUSH    AF
                LD      A,C
                OR      #9F
                INC     A
                JR      NZ,REPORT_C
                POP     AF
                JR      VAR_A_1

; Command classes
; 06 - numeric expression is expected
; 08 - two numeric expressions separated by comma are expected
; 0A - string expression is expected
NEXT_2NUM:      RST     #20
EXPT_2NUM:      CALL    EXPT_1NUM               ; CLASS_08
                CP      #2C
                JR      NZ,REPORT_C
                RST     #20
EXPT_1NUM:      CALL    SCANNING                ; CLASS_06
                BIT     6,(IY+#01)
                RET     NZ
REPORT_C:       RST     #08                     ; Error report
                DB      #0B                     ; Nonsense in BASIC
EXPT_EXP:       CALL    SCANNING                ; CLASS_0A
                BIT     6,(IY+#01)
                RET     Z
                JR      REPORT_C

; Command class 07 - set permanent colors
CLASS_07:       BIT     7,(IY+#01)
                RES     0,(IY+#02)
                CALL    NZ,TEMPS
                POP     AF
                LD      A,(#5C74)
                SUB     #13
                CALL    CO_TEMP_4
                CALL    CHECK_END
                LD      HL,(#5C8F)
                LD      (#5C8D),HL
                LD      HL,#5C91
                LD      A,(HL)
                RLCA
                XOR     (HL)
                AND     #AA
                XOR     (HL)
                LD      (HL),A
                RET

; Command class 09 - two coordinates, could be preceded by embedded color commands
CLASS_09:       CALL    SYNTAX_Z
                JR      Z,CL_09_1
                RES     0,(IY+#02)
                CALL    TEMPS
                LD      HL,#5C90
                LD      A,(HL)
                OR      #F8
                LD      (HL),A
                RES     6,(IY+#57)
                RST     #18
CL_09_1:        CALL    CO_TEMP_2
                JR      EXPT_2NUM

; Command class 09 - four commands handling
                JP      SAVE_ETC

; Fetch a number
FETCH_NUM:      CP      #0D
                JR      Z,USE_ZERO
                CP      #3A
                JR      NZ,EXPT_1NUM           
USE_ZERO:       CALL    SYNTAX_Z                ; Place 0 on the calculator stack
                RET     Z
                RST     #28                     ;FP_CALC
                DB      #A0                     ;STK_ZERO
                DB      #38                     ;END_CALC
                RET

; Handle STOP command
STOP:           RST     #08                     ; Error report
                DB      #08                     ; STOP statement

; Handle IF command
IF_CMD:         POP     BC
                CALL    SYNTAX_Z
                JR      Z,IF_1
                RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                EX      DE,HL
                CALL    TEST_ZERO
                JP      C,LINE_END
IF_1:           JP      STMT_L_1

; Handle FOR command
FOR:            CP      #CD
                JR      NZ,F_USE_1
                RST     #20
                CALL    EXPT_1NUM
                CALL    CHECK_END
                JR      F_REORDER

F_USE_1:        CALL    CHECK_END
                RST     #28                     ;FP_CALC
                DB      #A1                     ;STK_ONE
                DB      #38                     ;END_CALC
F_REORDER:      RST     #28                     ;FP_CALC
                DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #01                     ;EXCHANGE
                DB      #E0                     ;GET_MEM_0
                DB      #01                     ;EXCHANGE
                DB      #38                     ;END_CALC
                CALL    LET
                LD      (#5C68),HL
                DEC     HL
                LD      A,(HL)
                SET     7,(HL)
                LD      BC,#0006
                ADD     HL,BC
                RLCA
                JR      C,F_L_S
                LD      C,#0D
                CALL    MAKE_ROOM
                INC     HL
F_L_S:          PUSH    HL
                RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                POP     HL
                EX      DE,HL
                LD      C,#0A
                LDIR
                LD      HL,(#5C45)
                EX      DE,HL
                LD      (HL),E
                INC     HL
                LD      (HL),D
                LD      D,(IY+#0D)
                INC     D
                INC     HL
                LD      (HL),D
                CALL    NEXT_LOOP
                RET     NC
                LD      B,(IY+#38)
                LD      HL,(#5C45)
                LD      (#5C42),HL
                LD      A,(#5C47)
                NEG
                LD      D,A
                LD      HL,(#5C5D)
                LD      E,#F3
F_LOOP:         PUSH    BC
                LD      BC,(#5C55)
                CALL    LOOK_PROG
                LD      (#5C55),BC
                POP     BC
                JR      C,REPORT_I
                RST     #20
                OR      #20
                CP      B
                JR      Z,F_FOUND
                RST     #20
                JR      F_LOOP

F_FOUND:        RST     #20
                LD      A,#01
                SUB     D
                LD      (#5C44),A
                RET

REPORT_I:       RST     #08                     ; Error report
                DB      #11                     ; FOR without NEXT

; Search the program area for DATA, DEF FN or NEXT keywords
LOOK_PROG:      LD      A,(HL)
                CP      #3A
                JR      Z,LOOK_P_2
LOOK_P_1:       INC     HL
                LD      A,(HL)
                AND     #C0
                SCF
                RET     NZ
                LD      B,(HL)
                INC     HL
                LD      C,(HL)
                LD      (#5C42),BC
                INC     HL
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                PUSH    HL
                ADD     HL,BC
                LD      B,H
                LD      C,L
                POP     HL
                LD      D,#00
LOOK_P_2:       PUSH    BC
                CALL    EACH_STMT
                POP     BC
                RET     NC
                JR      LOOK_P_1

; Handle NEXT command
NEXT:           BIT     1,(IY+#37)
                JP      NZ,REPORT_2
                LD      HL,(#5C4D)
                BIT     7,(HL)
                JR      Z,REPORT_1
                INC     HL
                LD      (#5C68),HL
                RST     #28                     ;FP_CALC
                DB      #E0                     ;GET_MEM_0
                DB      #E2                     ;GET_MEM_2
                DB      #0F                     ;ADDITION
                DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                CALL    NEXT_LOOP
                RET     C
                LD      HL,(#5C68)
                LD      DE,#000F
                ADD     HL,DE
                LD      E,(HL)
                INC     HL
                LD      D,(HL)
                INC     HL
                LD      H,(HL)
                EX      DE,HL
                JP      GO_TO_2

REPORT_1:       RST     #08                     ; Error report
                DB      #00                     ; NEXT withou FOR

; Test iterations for FOR command
NEXT_LOOP:      RST     #28                     ;FP_CALC
                DB      #E1                     ;GET_MEM_1
                DB      #E0                     ;GET_MEM_0
                DB      #E2                     ;GET_MEM_2
                DB      #36                     ;LESS_0
                DB      #00                     ;JUMP_TRUE
                DB      #02                     ;NEXT_1 if step negative
                DB      #01                     ;EXCHANGE
NEXT_1:         DB      #03                     ;SUBTRACT
                DB      #37                     ;GREATER_0
                DB      #00                     ;JUMP_TRUE
                DB      #04                     ;NEXT_2 if finished
                DB      #38                     ;END_CALC
                AND     A
                RET
       
NEXT_2:         DB      #38                     ;END_CALC
                SCF
                RET

; Handle READ command
READ_3:         RST     #20
READ:           CALL    CLASS_01
                CALL    SYNTAX_Z
                JR      Z,READ_2
                RST     #18
                LD      (#5C5F),HL
                LD      HL,(#5C57)
                LD      A,(HL)
                CP      #2C
                JR      Z,READ_1
                LD      E,#E4
                CALL    LOOK_PROG
                JR      NC,READ_1
REPORT_E:       RST     #08                     ; Error report
                DB      #0D                     ; Out of data
READ_1:         CALL    TEMP_PTR1
                CALL    VAL_FET_1
                RST     #18
                LD      (#5C57),HL
                LD      HL,(#5C5F)
                LD      (IY+#26),#00
                CALL    TEMP_PTR2
READ_2:         RST     #18
                CP      #2C
                JR      Z,READ_3
                CALL    CHECK_END
                RET

; Handle DATA command
DATA:           CALL    SYNTAX_Z
                JR      NZ,DATA_2
DATA_1:         CALL    SCANNING
                CP      #2C
                CALL    NZ,CHECK_END
                RST     #20
                JR      DATA_1

DATA_2:         LD      A,#E4
PASS_BY:        LD      B,A
                CPDR
                LD      DE,#0200
                JP      EACH_STMT

; Handle RESTORE command
RESTORE:        CALL    FIND_INT2
REST_RUN:       LD      H,B
                LD      L,C
                CALL    LINE_ADDR
                DEC     HL
                LD      (#5C57),HL
                RET

; Handle RANDOMIZE command
RANDOMIZE:      CALL    FIND_INT2
                LD      A,B
                OR      C
                JR      NZ,RAND_1
                LD      BC,(#5C78)
RAND_1:         LD      (#5C76),BC
                RET

; Handle CONTINUE command
CONTINUE:       LD      HL,(#5C6E)
                LD      D,(IY+#36)
                JR      GO_TO_2

; Handle GOTO command
GO_TO:          CALL    FIND_INT2
                LD      H,B
                LD      L,C
                LD      D,#00
                LD      A,H
                CP      #F0
                JR      NC,REPORT_BB
GO_TO_2:        LD      (#5C42),HL
                LD      (IY+#0A),D
                RET

; Handle OUT command
OUT_CMD:        CALL    TWO_PARAM
                OUT     (C),A
                RET

; BSROM - fix for rewriting first bytes of ROM
; was POKE command handling here originally
NO_RW_AT0:      LD      DE,(#5C65)
                RET

; BSROM - extended command parameters
TWO_PARAM:      CALL    FP_TO_A
                PUSH    AF
                CALL    FIND_INT2
                POP     AF
ROZPAR:         JR      C,REPORT_BB
                JR      Z,ROZPAR_1
                NEG
ROZPAR_1:       RET

; Find integers
FIND_INT1:      CALL    FP_TO_A
                JR      ROZPAR

FIND_INT2:      CALL    FP_TO_BC
                JR      C,REPORT_BB
                RET     Z

REPORT_BB:      RST     #08                     ; Error report
                DB      #0A                     ; Integer out of range

; Handle RUN command
RUN:            CALL    GO_TO
                LD      BC,#0000
                CALL    REST_RUN
                JR      CLEAR_RUN

; Handle CLEAR command
CLEAR:          CALL    FIND_INT2
CLEAR_RUN:      LD      A,B
                OR      C
                JR      NZ,CLEAR_1
                LD      BC,(#5CB2)
CLEAR_1:        PUSH    BC
                LD      DE,(#5C4B)
                LD      HL,(#5C59)
                DEC     HL
                CALL    RECLAIM_1
                CALL    CLS
                LD      HL,(#5C65)
                LD      DE,#0032
                ADD     HL,DE
                POP     DE
                SBC     HL,DE
                JR      NC,REPORT_M
                LD      HL,(#5CB4)
                AND     A
                SBC     HL,DE
                JR      NC,CLEAR_2
REPORT_M:       RST     #08                     ; Error report
                DB      #15                     ; RAMTOP no good
CLEAR_2:        EX      DE,HL
                LD      (#5CB2),HL
                POP     DE
                POP     BC
                LD      (HL),#3E
                DEC     HL
                LD      SP,HL
                PUSH    BC
                LD      (#5C3D),SP
                EX      DE,HL
                JP      (HL)

; Handle GO SUB command
GO_SUB:         POP     DE
                LD      H,(IY+#0D)
                INC     H
                EX      (SP),HL
                INC     SP
                LD      BC,(#5C45)
                PUSH    BC
                PUSH    HL
                LD      (#5C3D),SP
                PUSH    DE
                CALL    GO_TO
                LD      BC,#0014
TEST_ROOM:      LD      HL,(#5C65)              ; Check available memory
                ADD     HL,BC
                JR      C,REPORT_4
                EX      DE,HL
                LD      HL,#0050
                ADD     HL,DE
                JR      C,REPORT_4
                SBC     HL,SP
                RET     C
REPORT_4:       LD      L,#03
                JP      ERROR_3

; Get free memory. Not used in ROM, but can be used by user
FREE_MEM:       LD      BC,#0000
                CALL    TEST_ROOM
                LD      B,H
                LD      C,L
                RET

; Handle RETURN command
RETURN:         POP     BC
                POP     HL
                POP     DE
                LD      A,D
                CP      #3E
                JR      Z,REPORT_7
                DEC     SP
                EX      (SP),HL
                EX      DE,HL
                LD      (#5C3D),SP
                PUSH    BC
                JP      GO_TO_2
REPORT_7:       PUSH    DE
                PUSH    HL
                RST     #08                     ; Error report
                DB      #06                     ; RETURN without GOSUB

; Handle PAUSE command
PAUSE:          CALL    FIND_INT2
PAUSE_1:        HALT
                DEC     BC
                LD      A,B
                OR      C
                JR      Z,PAUSE_END
                LD      A,B
                AND     C
                INC     A
                JR      NZ,PAUSE_2
                INC     BC
PAUSE_2:        BIT     5,(IY+#01)
                JR      Z,PAUSE_1
PAUSE_END:      RES     5,(IY+#01)
                RET

; Check for BREAK key
BREAK_KEY:      LD      A,#7F
                IN      A,(#FE)
                RRA
                RET     C
                LD      A,#FE
                IN      A,(#FE)
                RRA
                RET

; Handle DEF FN command
DEF_FN:         CALL    SYNTAX_Z
                JR      Z,DEF_FN_1
                LD      A,#CE
                JP      PASS_BY

DEF_FN_1:       SET     6,(IY+#01)
                CALL    ALPHA
                JR      NC,DEF_FN_4
                RST     #20
                CP      #24
                JR      NZ,DEF_FN_2
                RES     6,(IY+#01)
                RST     #20
DEF_FN_2:       CP      #28
                JR      NZ,DEF_FN_7
                RST     #20
                CP      #29
                JR      Z,DEF_FN_6
DEF_FN_3:       CALL    ALPHA
DEF_FN_4:       JP      NC,REPORT_C
                EX      DE,HL
                RST     #20
                CP      #24
                JR      NZ,DEF_FN_5
                EX      DE,HL
                RST     #20
DEF_FN_5:       EX      DE,HL
                LD      BC,#0006
                CALL    MAKE_ROOM
                INC     HL
                INC     HL
                LD      (HL),#0E
                CP      #2C
                JR      NZ,DEF_FN_6
                RST     #20
                JR      DEF_FN_3

DEF_FN_6:       CP      #29
                JR      NZ,DEF_FN_7
                RST     #20
                CP      #3D
                JR      NZ,DEF_FN_7
                RST     #20
                LD      A,(#5C3B)
                PUSH    AF
                CALL    SCANNING
                POP     AF
                XOR     (IY+#01)
                AND     #40
DEF_FN_7:       JP      NZ,REPORT_C
                CALL    CHECK_END
UNSTACK_Z:      CALL    SYNTAX_Z
                POP     HL
                RET     Z
                JP      (HL)

; Handle LPRINT command
LPRINT:         LD      A,#03
                JR      PRINT_1

; Handle PRINT command
PRINT:          LD      A,#02
PRINT_1:        CALL    SYNTAX_Z
                CALL    NZ,CHAN_OPEN
                CALL    TEMPS
                CALL    PRINT_2
                CALL    CHECK_END
                RET

PRINT_2:        RST     #18
                CALL    PR_END_Z
                JR      Z,PRINT_4
PRINT_3:        CALL    PR_POSN_1
                JR      Z,PRINT_3
                CALL    PR_ITEM_1
                CALL    PR_POSN_1
                JR      Z,PRINT_3
PRINT_4:        CP      #29
                RET     Z
PRINT_CR:       CALL    UNSTACK_Z
PRINT_5:        LD      A,#0D
                RST     #10
                RET

; Print items
PR_ITEM_1:      RST     #18
                CP      #AC
                JR      NZ,PR_ITEM_2
                CALL    NEXT_2NUM
                CALL    UNSTACK_Z
                CALL    STK_TO_BC
                LD      A,#16
                JR      PR_AT_TAB

PR_ITEM_2:      CP      #AD
                JR      NZ,PR_ITEM_3
                RST     #20
                CALL    EXPT_1NUM
                CALL    UNSTACK_Z
                CALL    FIND_INT2
                LD      A,#17
PR_AT_TAB:      RST     #10
                LD      A,C
                RST     #10
                LD      A,B
                RST     #10
                RET

PR_ITEM_3:      CALL    CO_TEMP_3
                RET     NC
                CALL    STR_ALTER
                RET     NC
                CALL    SCANNING
                CALL    UNSTACK_Z
                BIT     6,(IY+#01)
                CALL    Z,STK_FETCH
                JP      NZ,PRINT_FP
PR_STRING:      LD      A,B
                OR      C
                DEC     BC
                RET     Z
                LD      A,(DE)
                INC     DE
                RST     #10
                JR      PR_STRING

; End of printing
PR_END_Z:       CP      #29                     ; ')'
                RET     Z
PR_ST_END:      CP      #0D                     ; carriage return
                RET     Z
                CP      #3A                     ; ':'
                RET

; Consider print position by ';' or ',' or '''
PR_POSN_1:      RST     #18
                CP      #3B
                JR      Z,PR_POSN_3
                CP      #2C
                JR      NZ,PR_POSN_2
                CALL    SYNTAX_Z
                JR      Z,PR_POSN_3
                LD      A,#06
                RST     #10
                JR      PR_POSN_3

PR_POSN_2:      CP      #27
                RET     NZ
                CALL    PRINT_CR
PR_POSN_3:      RST     #20
                CALL    PR_END_Z
                JR      NZ,PR_POSN_4
                POP     BC
PR_POSN_4:      CP      A
                RET

; Alter stream
STR_ALTER:      CP      #23
                SCF
                RET     NZ
                RST     #20
                CALL    EXPT_1NUM
                AND     A
                CALL    UNSTACK_Z
                CALL    FIND_INT1
                CP      #10
                JP      NC,REPORT_OA
                CALL    CHAN_OPEN
                AND     A
                RET

; Handle INPUT command
INPUT:          CALL    SYNTAX_Z
                JR      Z,INPUT_1
                LD      A,#01
                CALL    CHAN_OPEN
                CALL    CLS_LOWER
INPUT_1:        LD      (IY+#02),#01
                CALL    IN_ITEM_1
                CALL    CHECK_END
                LD      BC,(#5C88)
                LD      A,(#5C6B)
                CP      B
                JR      C,INPUT_2
                LD      C,#21
                LD      B,A
INPUT_2:        LD      (#5C88),BC
                LD      A,#19
                SUB     B
                LD      (#5C8C),A
                RES     0,(IY+#02)
                CALL    CL_SET
                JP      CLS_LOWER

; Handle input items from the current input channel
IN_ITEM_1:      CALL    PR_POSN_1
                JR      Z,IN_ITEM_1
                CP      #28
                JR      NZ,IN_ITEM_2
                RST     #20
                CALL    PRINT_2
                RST     #18
                CP      #29
                JP      NZ,REPORT_C
                RST     #20
                JP      IN_NEXT_2

IN_ITEM_2:      CP      #CA
                JR      NZ,IN_ITEM_3
                RST     #20
                CALL    CLASS_01
                SET     7,(IY+#37)
                BIT     6,(IY+#01)
                JP      NZ,REPORT_C
                JR      IN_PROMPT

IN_ITEM_3:      CALL    ALPHA
                JP      NC,IN_NEXT_1
                CALL    CLASS_01
                RES     7,(IY+#37)
IN_PROMPT:      CALL    SYNTAX_Z
                JP      Z,IN_NEXT_2
                CALL    SET_WORK
                LD      HL,#5C71
                RES     6,(HL)
                SET     5,(HL)
                LD      BC,#0001
                BIT     7,(HL)
                JR      NZ,IN_PR_2
                LD      A,(#5C3B)
                AND     #40
                JR      NZ,IN_PR_1
                LD      C,#03
IN_PR_1:        OR      (HL)
                LD      (HL),A
IN_PR_2:        RST     #30
                LD      (HL),#0D
                LD      A,C
                RRCA
                RRCA
                JR      NC,IN_PR_3
                LD      A,#22
                LD      (DE),A
                DEC     HL
                LD      (HL),A
IN_PR_3:        LD      (#5C5B),HL
                BIT     7,(IY+#37)
                JR      NZ,IN_VAR_3
                LD      HL,(#5C5D)
                PUSH    HL
                LD      HL,(#5C3D)
                PUSH    HL
IN_VAR_1:       LD      HL,IN_VAR_1
                PUSH    HL
                BIT     4,(IY+#30)
                JR      Z,IN_VAR_2
                LD      (#5C3D),SP
IN_VAR_2:       LD      HL,(#5C61)
                CALL    REMOVE_FP
                LD      (IY+#00),#FF
                CALL    EDITOR
                RES     7,(IY+#01)
                CALL    IN_ASSIGN
                JR      IN_VAR_4

IN_VAR_3:       CALL    EDITOR
IN_VAR_4:       LD      (IY+#22),#00
                CALL    IN_CHAN_K
                JR      NZ,IN_VAR_5
                CALL    ED_COPY
                LD      BC,(#5C82)
                CALL    CL_SET
IN_VAR_5:       LD      HL,#5C71
                RES     5,(HL)
                BIT     7,(HL)
                RES     7,(HL)
                JR      NZ,IN_VAR_6
                POP     HL
                POP     HL
                LD      (#5C3D),HL
                POP     HL
                LD      (#5C5F),HL
                SET     7,(IY+#01)
                CALL    IN_ASSIGN
                LD      HL,(#5C5F)
                LD      (IY+#26),#00
                LD      (#5C5D),HL
                JR      IN_NEXT_2

IN_VAR_6:       LD      HL,(#5C63)
                LD      DE,(#5C61)
                SCF
                SBC     HL,DE
                LD      B,H
                LD      C,L
                CALL    STK_STO_D
                CALL    LET
                JR      IN_NEXT_2

IN_NEXT_1:      CALL    PR_ITEM_1
IN_NEXT_2:      CALL    PR_POSN_1
                JP      Z,IN_ITEM_1
                RET

; INPUT sytax check and assignment
IN_ASSIGN:      LD      HL,(#5C61)
                LD      (#5C5D),HL
                RST     #18
                CP      #E2                     ; STOP
                JR      Z,IN_STOP
                LD      A,(#5C71)
                CALL    VAL_FET_2
                RST     #18
                CP      #0D                     ; carriage return
                RET     Z
REPORT_CB:      RST     #08                     ; Error report
                DB      #0B                     ; Nonsense in BASIC
IN_STOP:        CALL    SYNTAX_Z
                RET     Z
REPORT_H:       RST     #08                     ; Error report
                DB      #10                     ; STOP in INPUT
IN_CHAN_K:      LD      HL,(#5C51)              ; Test for K channel
                INC     HL
                INC     HL
                INC     HL
                INC     HL
                LD      A,(HL)
                CP      #4B
                RET

; Color item routines
CO_TEMP_1:      RST     #20
CO_TEMP_2:      CALL    CO_TEMP_3
                RET     C
                RST     #18
                CP      #2C
                JR      Z,CO_TEMP_1
                CP      #3B
                JR      Z,CO_TEMP_1
                JP      REPORT_C

CO_TEMP_3:      CP      #D9
                RET     C
                CP      #DF
                CCF
                RET     C
                PUSH    AF
                RST     #20
                POP     AF
CO_TEMP_4:      SUB     #C9
                PUSH    AF
                CALL    EXPT_1NUM
                POP     AF
                AND     A
                CALL    UNSTACK_Z
                PUSH    AF
                CALL    FIND_INT1
                LD      D,A
                POP     AF
                RST     #10
                LD      A,D
                RST     #10
                RET

; The color system variable handler
CO_TEMP_5:      SUB     #11
                ADC     A,#00
                JR      Z,CO_TEMP_7
                SUB     #02
                ADC     A,#00
                JR      Z,CO_TEMP_C
                CP      #01
                LD      A,D
                LD      B,#01
                JR      NZ,CO_TEMP_6
                RLCA
                RLCA
                LD      B,#04
CO_TEMP_6:      LD      C,A
                LD      A,D
                CP      #02
                JR      NC,REPORT_K
                LD      A,C
                LD      HL,#5C91
                JR      CO_CHANGE
CO_TEMP_7:      LD      A,D
                LD      B,#07
                JR      C,CO_TEMP_8
                RLCA
                RLCA
                RLCA
                LD      B,#38
CO_TEMP_8:      LD      C,A
                LD      A,D
                CP      #0A
                JR      C,CO_TEMP_9
REPORT_K:       RST     #08                     ; Error report
                DB      #13                     ; Invalid colour
CO_TEMP_9:      LD      HL,#5C8F
                CP      #08
                JR      C,CO_TEMP_B
                LD      A,(HL)
                JR      Z,CO_TEMP_A
                OR      B
                CPL
                AND     #24
                JR      Z,CO_TEMP_A
                LD      A,B
CO_TEMP_A:      LD      C,A
CO_TEMP_B:      LD      A,C
                CALL    CO_CHANGE
                LD      A,#07
                CP      D
                SBC     A,A
                CALL    CO_CHANGE
                RLCA
                RLCA
                AND     #50
                LD      B,A
                LD      A,#08
                CP      D
                SBC     A,A

; Handle change of color
CO_CHANGE:      XOR     (HL)
                AND     B
                XOR     (HL)
                LD      (HL),A
                INC     HL
                LD      A,B
                RET

CO_TEMP_C:      SBC     A,A
                LD      A,D
                RRCA
                LD      B,#80
                JR      NZ,CO_TEMP_D
                RRCA
                LD      B,#40
CO_TEMP_D:      LD      C,A
                LD      A,D
                CP      #08
                JR      Z,CO_TEMP_E
                CP      #02
                JR      NC,REPORT_K
CO_TEMP_E:      LD      A,C
                LD      HL,#5C8F
                CALL    CO_CHANGE
                LD      A,C
                RRCA
                RRCA
                RRCA
                JR      CO_CHANGE

; Handle BORDER command
BORDER:         CALL    FIND_INT1
                CP      #08
                JR      NC,REPORT_K
                OUT     (#FE),A
                RLCA
                RLCA
                RLCA
                BIT     5,A
                JR      NZ,BORDER_1
                XOR     #07
BORDER_1:       LD      (#5C48),A
                RET

; Get pixel address
PIXEL_ADD:      LD      A,#AF
                SUB     B
                JP      C,REPORT_BC
                LD      B,A
                AND     A
                RRA
                SCF
                RRA
                AND     A
                RRA
                XOR     B
                AND     #F8
                XOR     B
                LD      H,A
                LD      A,C
                RLCA
                RLCA
                RLCA
                XOR     B
                AND     #C7
                XOR     B
                RLCA
                RLCA
                LD      L,A
                LD      A,C
                AND     #07
                RET

; Point subroutine
POINT_SUB:      CALL    STK_TO_BC
                CALL    PIXEL_ADD
                LD      B,A
                INC     B
                LD      A,(HL)
POINT_LP:       RLCA
                DJNZ    POINT_LP
                AND     #01
                JP      STACK_A

; Handle PLOT command
PLOT:           CALL    STK_TO_BC
                CALL    PLOT_SUB
                JP      TEMPS

PLOT_SUB:       LD      (#5C7D),BC
                CALL    PIXEL_ADD
                LD      B,A
                INC     B
                LD      A,#FE
PLOT_LOOP:      RRCA
                DJNZ    PLOT_LOOP
                LD      B,A
                LD      A,(HL)
                LD      C,(IY+#57)
                BIT     0,C
                JR      NZ,PL_TST_IN
                AND     B
PL_TST_IN:      BIT     2,C
                JR      NZ,PLOT_END
                XOR     B
                CPL
PLOT_END:       LD      (HL),A
                JP      PO_ATTR

; Put two numbers in BC register
STK_TO_BC:      CALL    STK_TO_A
                LD      B,A
                PUSH    BC
                CALL    STK_TO_A
                LD      E,C
                POP     BC
                LD      D,C
                LD      C,A
                RET

; Put the last value on the calc stack into the accumulator
STK_TO_A:       CALL    FP_TO_A
                JP      C,REPORT_BC
                LD      C,#01
                RET     Z
                LD      C,#FF
                RET

; Handle CIRCLE command
CIRCLE:         RST     #18
                CP      #2C
                JP      NZ,REPORT_C
                RST     #20
                CALL    EXPT_1NUM
                CALL    CHECK_END
                RST     #28                     ;FP_CALC
                DB      #2A                     ;ABS
                DB      #3D                     ;RE_STACK
                DB      #38                     ;END_CALC
                LD      A,(HL)
                CP      #81
                JR      NC,C_R_GRE_1
                RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                JR      PLOT

C_R_GRE_1:      RST     #28                     ;FP_CALC
                DB      #A3                     ;STK_PI_2
                DB      #38                     ;END_CALC
                LD      (HL),#83
                RST     #28                     ;FP_CALC
                DB      #C5                     ;ST_MEM_5
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                CALL    CD_PRMS1
                PUSH    BC
                RST     #28                     ;FP_CALC
                DB      #31                     ;DUPLICATE
                DB      #E1                     ;GET_MEM_1
                DB      #04                     ;MULTIPLY
                DB      #38                     ;END_CALC
                LD      A,(HL)
                CP      #80
                JR      NC,C_ARC_GE1
                RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                POP     BC
                JP      PLOT

C_ARC_GE1:      RST     #28                     ;FP_CALC
                DB      #C2                     ;ST_MEM_2
                DB      #01                     ;EXCHANGE
                DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #03                     ;SUBTRACT
                DB      #01                     ;EXCHANGE
                DB      #E0                     ;GET_MEM_0
                DB      #0F                     ;ADDITION
                DB      #C0                     ;ST_MEM_0
                DB      #01                     ;EXCHANGE
                DB      #31                     ;DUPLICATE
                DB      #E0                     ;GET_MEM_0
                DB      #01                     ;EXCHANGE
                DB      #31                     ;DUPLICATE
                DB      #E0                     ;GET_MEM_0
                DB      #A0                     ;STK_ZERO
                DB      #C1                     ;ST_MEM_1
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                INC     (IY+#62)
                CALL    FIND_INT1
                LD      L,A
                PUSH    HL
                CALL    FIND_INT1
                POP     HL
                LD      H,A
                LD      (#5C7D),HL
                POP     BC
                JP      DRW_STEPS

; Handle DRAW command
DRAW:           RST     #18
                CP      #2C
                JR      Z,DR_3_PRMS
                CALL    CHECK_END
                JP      LINE_DRAW

DR_3_PRMS:      RST     #20
                CALL    EXPT_1NUM
                CALL    CHECK_END
                RST     #28                     ;FP_CALC
                DB      #C5                     ;ST_MEM_5
                DB      #A2                     ;STK_HALF
                DB      #04                     ;MULTIPLY
                DB      #1F                     ;SIN
                DB      #31                     ;DUPLICATE
                DB      #30                     ;NOT
                DB      #30                     ;NOT
                DB      #00                     ;JUMP_TRUE
                DB      #06                     ;to DR_SIN_NZ
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                JP      LINE_DRAW

DR_SIN_NZ:      DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #C1                     ;ST_MEM_1
                DB      #02                     ;DELETE
                DB      #31                     ;DUPLICATE
                DB      #2A                     ;ABS
                DB      #E1                     ;GET_MEM_1
                DB      #01                     ;EXCHANGE
                DB      #E1                     ;GET_MEM_1
                DB      #2A                     ;ABS
                DB      #0F                     ;ADDITION
                DB      #E0                     ;GET_MEM_0
                DB      #05                     ;DIVISION
                DB      #2A                     ;ABS
                DB      #E0                     ;GET_MEM_0
                DB      #01                     ;EXCHANGE
                DB      #3D                     ;RE_STACK
                DB      #38                     ;END_CALC
                LD      A,(HL)
                CP      #81
                JR      NC,DR_PRMS
                RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                JP      LINE_DRAW

DR_PRMS:        CALL    CD_PRMS1
                PUSH    BC
                RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #E1                     ;GET_MEM_1
                DB      #01                     ;EXCHANGE
                DB      #05                     ;DIVISION
                DB      #C1                     ;ST_MEM_1
                DB      #02                     ;DELETE
                DB      #01                     ;EXCHANGE
                DB      #31                     ;DUPLICATE
                DB      #E1                     ;GET_MEM_1
                DB      #04                     ;MULTIPLY
                DB      #C2                     ;ST_MEM_2
                DB      #02                     ;DELETE
                DB      #01                     ;EXCHANGE
                DB      #31                     ;DUPLICATE
                DB      #E1                     ;GET_MEM_1
                DB      #04                     ;MULTIPLY
                DB      #E2                     ;GET_MEM_2
                DB      #E5                     ;GET_MEM_5
                DB      #E0                     ;GET_MEM_0
                DB      #03                     ;SUBTRACT
                DB      #A2                     ;STK_HALF
                DB      #04                     ;MULTIPLY
                DB      #31                     ;DUPLICATE
                DB      #1F                     ;SIN
                DB      #C5                     ;ST_MEM_5
                DB      #02                     ;DELETE
                DB      #20                     ;COS
                DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #C2                     ;ST_MEM_2
                DB      #02                     ;DELETE
                DB      #C1                     ;ST_MEM_1
                DB      #E5                     ;GET_MEM_5
                DB      #04                     ;MULTIPLY
                DB      #E0                     ;GET_MEM_0
                DB      #E2                     ;GET_MEM_2
                DB      #04                     ;MULTIPLY
                DB      #0F                     ;ADDITION
                DB      #E1                     ;GET_MEM_1
                DB      #01                     ;EXCHANGE
                DB      #C1                     ;ST_MEM_1
                DB      #02                     ;DELETE
                DB      #E0                     ;GET_MEM_0
                DB      #04                     ;MULTIPLY
                DB      #E2                     ;GET_MEM_2
                DB      #E5                     ;GET_MEM_5
                DB      #04                     ;MULTIPLY
                DB      #03                     ;SUBTRACT
                DB      #C2                     ;ST_MEM_2
                DB      #2A                     ;ABS
                DB      #E1                     ;GET_MEM_1
                DB      #2A                     ;ABS
                DB      #0F                     ;ADDITION
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                LD      A,(DE)
                CP      #81
                POP     BC
                JP      C,LINE_DRAW
                PUSH    BC
                RST     #28                     ;FP_CALC
                DB      #01                     ;EXCHANGE
                DB      #38                     ;END_CALC
                LD      A,(#5C7D)
                CALL    STACK_A
                RST     #28                     ;FP_CALC
                DB      #C0                     ;ST_MEM_0
                DB      #0F                     ;ADDITION
                DB      #01                     ;EXCHANGE
                DB      #38                     ;END_CALC
                LD      A,(#5C7E)
                CALL    STACK_A
                RST     #28                     ;FP_CALC
                DB      #C5                     ;ST_MEM_5
                DB      #0F                     ;ADDITION
                DB      #E0                     ;GET_MEM_0
                DB      #E5                     ;GET_MEM_5
                DB      #38                     ;END_CALC
                POP     BC
DRW_STEPS:      DEC     B
                JR      Z,ARC_END
                JR      ARC_START

ARC_LOOP:       RST     #28                     ;FP_CALC
                DB      #E1                     ;GET_MEM_1
                DB      #31                     ;DUPLICATE
                DB      #E3                     ;GET_MEM_3
                DB      #04                     ;MULTIPLY
                DB      #E2                     ;GET_MEM_2
                DB      #E4                     ;GET_MEM_4
                DB      #04                     ;MULTIPLY
                DB      #03                     ;SUBTRACT
                DB      #C1                     ;ST_MEM_1
                DB      #02                     ;DELETE
                DB      #E4                     ;GET_MEM_4
                DB      #04                     ;MULTIPLY
                DB      #E2                     ;GET_MEM_2
                DB      #E3                     ;GET_MEM_3
                DB      #04                     ;MULTIPLY
                DB      #0F                     ;ADDITION
                DB      #C2                     ;ST_MEM_2
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
ARC_START:      PUSH    BC
                RST     #28                     ;FP_CALC
                DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #E1                     ;GET_MEM_1
                DB      #0F                     ;ADDITION
                DB      #31                     ;DUPLICATE
                DB      #38                     ;END_CALC
                LD      A,(#5C7D)
                CALL    STACK_A
                RST     #28                     ;FP_CALC
                DB      #03                     ;SUBTRACT
                DB      #E0                     ;GET_MEM_0
                DB      #E2                     ;GET_MEM_2
                DB      #0F                     ;ADDITION
                DB      #C0                     ;ST_MEM_0
                DB      #01                     ;EXCHANGE
                DB      #E0                     ;GET_MEM_0
                DB      #38                     ;END_CALC
                LD      A,(#5C7E)
                CALL    STACK_A
                RST     #28                     ;FP_CALC
                DB      #03                     ;SUBTRACT
                DB      #38                     ;END_CALC
                CALL    DRAW_LINE
                POP     BC
                DJNZ    ARC_LOOP
ARC_END:        RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #02                     ;DELETE
                DB      #01                     ;EXCHANGE
                DB      #38                     ;END_CALC
                LD      A,(#5C7D)
                CALL    STACK_A
                RST     #28                     ;FP_CALC
                DB      #03                     ;SUBTRACT
                DB      #01                     ;EXCHANGE
                DB      #38                     ;END_CALC
                LD      A,(#5C7E)
                CALL    STACK_A
                RST     #28                     ;FP_CALC
                DB      #03                     ;SUBTRACT
                DB      #38                     ;END_CALC
LINE_DRAW:      CALL    DRAW_LINE
                JP      TEMPS

; Initial parameters
CD_PRMS1:       RST     #28                     ;FP_CALC
                DB      #31                     ;DUPLICATE
                DB      #28                     ;SQR
                DB      #34                     ;STK_DATA
                DB      #32                     ;EXPONENT
                DB      #00                     ;
                DB      #01                     ;EXCHANGE
                DB      #05                     ;DIVISION
                DB      #E5                     ;GET_MEM_5
                DB      #01                     ;EXCHANGE
                DB      #05                     ;DIVISION
                DB      #2A                     ;ABS
                DB      #38                     ;END_CALC
                CALL    FP_TO_A
                JR      C,USE_252
                AND     #FC
                ADD     A,#04
                JR      NC,DRAW_SAVE
USE_252:        LD      A,#FC
DRAW_SAVE:      PUSH    AF
                CALL    STACK_A
                RST     #28                     ;FP_CALC
                DB      #E5                     ;GET_MEM_5
                DB      #01                     ;EXCHANGE
                DB      #05                     ;DIVISION
                DB      #31                     ;DUPLICATE
                DB      #1F                     ;SIN
                DB      #C4                     ;ST_MEM_4
                DB      #02                     ;DELETE
                DB      #31                     ;DUPLICATE
                DB      #A2                     ;STK_HALF
                DB      #04                     ;MULTIPLY
                DB      #1F                     ;SIN
                DB      #C1                     ;ST_MEM_1
                DB      #01                     ;EXCHANGE
                DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #31                     ;DUPLICATE
                DB      #04                     ;MULTIPLY
                DB      #31                     ;DUPLICATE
                DB      #0F                     ;ADDITION
                DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
                DB      #1B                     ;NEGATE
                DB      #C3                     ;ST_MEM_3
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                POP     BC
                RET

; Line drawing
DRAW_LINE:      CALL    STK_TO_BC
                LD      A,C
                CP      B
                JR      NC,DL_X_GE_Y
                LD      L,C
                PUSH    DE
                XOR     A
                LD      E,A
                JR      DL_LARGER

DL_X_GE_Y:      OR      C
                RET     Z
                LD      L,B
                LD      B,C
                PUSH    DE
                LD      D,#00
DL_LARGER:      LD      H,B
                LD      A,B
                RRA
D_L_LOOP:       ADD     A,L
                JR      C,D_L_DIAG
                CP      H
                JR      C,D_L_HR_VT
D_L_DIAG:       SUB     H
                LD      C,A
                EXX
                POP     BC
                PUSH    BC
                JR      D_L_STEP

D_L_HR_VT:      LD      C,A
                PUSH    DE
                EXX
                POP     BC
D_L_STEP:       LD      HL,(#5C7D)
                LD      A,B
                ADD     A,H
                LD      B,A
                LD      A,C
                INC     A
                ADD     A,L
                JR      C,D_L_RANGE
                JR      Z,REPORT_BC
D_L_PLOT:       DEC     A
                LD      C,A
                CALL    PLOT_SUB
                EXX
                LD      A,C
                DJNZ    D_L_LOOP
                POP     DE
                RET

D_L_RANGE:      JR      Z,D_L_PLOT
REPORT_BC:      RST     #08                     ; Error report
                DB      #0A                     ; Integer out of range

; Scan expression or sub expression
SCANNING:       RST     #18
                LD      B,#00
                PUSH    BC
S_LOOP_1:       LD      C,A
                CALL    HEXA                    ; BSROM - hexadecimal numbers handling
                CALL    INDEXER
                LD      A,C
                JP      NC,S_ALPHNUM
                LD      B,#00
                LD      C,(HL)
                ADD     HL,BC
                JP      (HL)

S_QUOTE_S:      CALL    CH_ADD_1
                INC     BC
                CP      #0D
                JP      Z,REPORT_C
                CP      #22
                JR      NZ,S_QUOTE_S
                CALL    CH_ADD_1
                CP      #22
                RET

S_2_COORD:      RST     #20
                CP      #28
                JR      NZ,S_RPORT_C
                CALL    NEXT_2NUM
                RST     #18
                CP      #29
S_RPORT_C:      JP      NZ,REPORT_C

; Check syntax
SYNTAX_Z:       BIT     7,(IY+#01)
                RET

; Scanning SCREEN$
S_SCRN_S:       CALL    STK_TO_BC
                LD      HL,(#5C36)
                LD      DE,#0100
                ADD     HL,DE
                LD      A,C
                RRCA
                RRCA
                RRCA
                AND     #E0
                XOR     B
                LD      E,A
                LD      A,C
                AND     #18
                XOR     #40
                LD      D,A
                LD      B,#60
S_SCRN_LP:      PUSH    BC
                PUSH    DE
                PUSH    HL
                LD      A,(DE)
                XOR     (HL)
                JR      Z,S_SC_MTCH
                INC     A
                JR      NZ,S_SCR_NXT
                DEC     A
S_SC_MTCH:      LD      C,A
                LD      B,#07
S_SC_ROWS:      INC     D
                INC     HL
                LD      A,(DE)
                XOR     (HL)
                XOR     C
                JR      NZ,S_SCR_NXT
                DJNZ    S_SC_ROWS
                POP     BC
                POP     BC
                POP     BC
                LD      A,#80
                SUB     B
                LD      BC,#0001
                RST     #30
                LD      (DE),A
                JR      S_SCR_STO

S_SCR_NXT:      POP     HL
                LD      DE,#0008
                ADD     HL,DE
                POP     DE
                POP     BC
                DJNZ    S_SCRN_LP
                LD      C,B
S_SCR_STO:      RET                             ; BSROM - bugfix - don't store string after SCREEN$
                DB      #B2,#2A                 ; remains of JP STK_STO_D (#2AB2)

; Scanning attributes
S_ATTR_S:       CALL    STK_TO_BC
                LD      A,C
                RRCA
                RRCA
                RRCA
                LD      C,A
                AND     #E0
                XOR     B
                LD      L,A
                LD      A,C
                AND     #03
                XOR     #58
                LD      H,A
                LD      A,(HL)
                JP      STACK_A

; Scanning function table
SCAN_FUNC:      DB      #22, #1C                ; S_QUOTE
                DB      #28, #4F                ; S_BRACKET
                DB      #2E, #F2                ; S_DECIMAL
                DB      #2B, #12                ; S_U_PLUS
                DB      #A8, #56                ; S_FN
                DB      #A5, #57                ; S_RND
                DB      #A7, #84                ; S_PI
                DB      #A6, #8F                ; S_INKEY
                DB      #C4, #E6                ; S_BIN
                DB      #AA, #BF                ; S_SCREEN
                DB      #AB, #C7                ; S_ATTR
                DB      #A9, #CE                ; S_POINT
                DB      #00                     ; End marker

; Scanning function routines
S_U_PLUS:       RST     #20
                JP      S_LOOP_1

S_QUOTE:        RST     #18
                INC     HL
                PUSH    HL
                LD      BC,#0000
                CALL    S_QUOTE_S
                JR      NZ,S_Q_PRMS
S_Q_AGAIN:      CALL    S_QUOTE_S
                JR      Z,S_Q_AGAIN
                CALL    SYNTAX_Z
                JR      Z,S_Q_PRMS
                RST     #30
                POP     HL
                PUSH    DE
S_Q_COPY:       LD      A,(HL)
                INC     HL
                LD      (DE),A
                INC     DE
                CP      #22
                JR      NZ,S_Q_COPY
                LD      A,(HL)
                INC     HL
                CP      #22
                JR      Z,S_Q_COPY
S_Q_PRMS:       DEC     BC
                POP     DE
S_STRING:       LD      HL,#5C3B
                RES     6,(HL)
                BIT     7,(HL)
                CALL    NZ,STK_STO_D
                JP      S_CONT_2

S_BRACKET:      RST     #20
                CALL    SCANNING
                CP      #29
                JP      NZ,REPORT_C
                RST     #20
                JP      S_CONT_2

S_FN:           JP      S_FN_SBRN

S_RND:          CALL    SYNTAX_Z
                JR      Z,S_RND_END
                LD      BC,(#5C76)
                CALL    STACK_BC
                RST     #28                     ;FP_CALC
                DB      #A1                     ;STK_ONE
                DB      #0F                     ;ADDITION
                DB      #34                     ;STK_DATA
                DB      #37                     ;Exponent
                DB      #16                     ;
                DB      #04                     ;MULTIPLY
                DB      #34                     ;STK_DATA
                DB      #80                     ;
                DB      #41                     ;Exponent
                DB      #00                     ;
                DB      #00                     ;
                DB      #80                     ;
                DB      #32                     ;N_MOD_M
                DB      #02                     ;DELETE
                DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
                DB      #31                     ;DUPLICATE
                DB      #38                     ;END_CALC
                CALL    FP_TO_BC
                LD      (#5C76),BC
                LD      A,(HL)
                AND     A
                JR      Z,S_RND_END
                SUB     #10
                LD      (HL),A
S_RND_END:      JR      S_PI_END

S_PI:           CALL    SYNTAX_Z
                JR      Z,S_PI_END
                RST     #28                     ;FP_CALC
                DB      #A3                     ;STK_PI_2
                DB      #38                     ;END_CALC
                INC     (HL)
S_PI_END:       RST     #20
                JP      S_NUMERIC

S_INKEY:        LD      BC,#105A
                RST     #20
                CP      #23
                JP      Z,S_PUSH_PO
                LD      HL,#5C3B
                RES     6,(HL)
                BIT     7,(HL)
                JR      Z,S_INK_EN
                CALL    KEY_SCAN
                LD      C,#00
                JR      NZ,S_IK_STK
                CALL    K_TEST
                JR      NC,S_IK_STK
                DEC     D
                LD      E,A
                CALL    K_DECODE
                PUSH    AF
                LD      BC,#0001
                RST     #30
                POP     AF
                LD      (DE),A
                LD      C,#01
S_IK_STK:       LD      B,#00
                CALL    STK_STO_D
S_INK_EN:       JP      S_CONT_2

S_SCREEN:       CALL    S_2_COORD
                CALL    NZ,S_SCRN_S
                RST     #20
                JP      S_STRING

S_ATTR:         CALL    S_2_COORD
                CALL    NZ,S_ATTR_S
                RST     #20
                JR      S_NUMERIC

S_POINT:        CALL    S_2_COORD
                CALL    NZ,POINT_SUB
                RST     #20
                JR      S_NUMERIC

S_ALPHNUM:      CALL    ALPHANUM
                JR      NC,S_NEGATE
                CP      #41
                JR      NC,S_LETTER
S_DECIMAL:             
S_BIN:          CALL    SYNTAX_Z
                JR      NZ,S_STK_DEC
                CALL    DEC_TO_FP
S_BIN_1:        RST     #18
                LD      BC,#0006
                CALL    MAKE_ROOM
                INC     HL
                LD      (HL),#0E
                INC     HL
                EX      DE,HL
                LD      HL,(#5C65)
                LD      C,#05
                AND     A
                SBC     HL,BC
                LD      (#5C65),HL
                LDIR
                EX      DE,HL
                DEC     HL
                CALL    TEMP_PTR1
                JR      S_NUMERIC

S_STK_DEC:      RST     #18
S_SD_SKIP:      INC     HL
                LD      A,(HL)
                CP      #0E
                JR      NZ,S_SD_SKIP
                INC     HL
                CALL    STACK_NUM
                LD      (#5C5D),HL
S_NUMERIC:      SET     6,(IY+#01)
                JR      S_CONT_1

; Scanning variable routines
S_LETTER:       CALL    LOOK_VARS
                JP      C,REPORT_2
                CALL    Z,STK_VAR
                LD      A,(#5C3B)
                CP      #C0
                JR      C,S_CONT_1
                INC     HL
                CALL    STACK_NUM
S_CONT_1:       JR      S_CONT_2

S_NEGATE:       LD      BC,#09DB
                CP      #2D
                JR      Z,S_PUSH_PO
                LD      BC,#1018
                CP      #AE
                JR      Z,S_PUSH_PO
                SUB     #AF
                JP      C,REPORT_C
                LD      BC,#04F0
                CP      #14
                JR      Z,S_PUSH_PO
                JP      NC,REPORT_C
                LD      B,#10
                ADD     A,#DC
                LD      C,A
                CP      #DF
                JR      NC,S_NO_TO
                RES     6,C
S_NO_TO:        CP      #EE
                JR      C,S_PUSH_PO
                RES     7,C
S_PUSH_PO:      PUSH    BC
                RST     #20
                JP      S_LOOP_1

S_CONT_2:       RST     #18
S_CONT_3:       CP      #28
                JR      NZ,S_OPERTR
                BIT     6,(IY+#01)
                JR      NZ,S_LOOP
                CALL    SLICING
                RST     #20
                JR      S_CONT_3

S_OPERTR:       LD      B,#00
                LD      C,A
                LD      HL,TBL_OF_OPS
                CALL    INDEXER
                JR      NC,S_LOOP
                LD      C,(HL)
                LD      HL,#26ED
                ADD     HL,BC
                LD      B,(HL)

; Scanning main loop
S_LOOP:         POP     DE
                LD      A,D
                CP      B
                JR      C,S_TIGHTER
                AND     A
                JP      Z,GET_CHAR
                PUSH    BC
                LD      HL,#5C3B
                LD      A,E
                CP      #ED
                JR      NZ,S_STK_LST
                BIT     6,(HL)
                JR      NZ,S_STK_LST
                LD      E,#99
S_STK_LST:      PUSH    DE
                CALL    SYNTAX_Z
                JR      Z,S_SYNTEST
                LD      A,E
                AND     #3F
                LD      B,A
                RST     #28                     ;FP_CALC
                DB      #3B                     ;FP_CALC_2
                DB      #38                     ;END_CALC
                JR      S_RUNTEST

S_SYNTEST:      LD      A,E
                CALL    VAL1                    ; BSROM - enhanced VAL & VAL$
                AND     #40
S_RPORT_C2:     JP      NZ,REPORT_C
S_RUNTEST:      POP     DE
                LD      HL,#5C3B
                SET     6,(HL)
                BIT     7,E
                JR      NZ,S_LOOPEND
                RES     6,(HL)
S_LOOPEND:      POP     BC
                JR      S_LOOP

S_TIGHTER:      PUSH    DE
                LD      A,C
                BIT     6,(IY+#01)
                JR      NZ,S_NEXT
                AND     #3F
                ADD     A,#08
                LD      C,A
                CP      #10
                JR      NZ,S_NOT_AND
                SET     6,C
                JR      S_NEXT

S_NOT_AND:      JR      C,S_RPORT_C2
                CP      #17
                JR      Z,S_NEXT
                SET     7,C
S_NEXT:         PUSH    BC
                RST     #20
                JP      S_LOOP_1

; Table of operators
TBL_OF_OPS:     DB      "+", #CF                ; ADDITION
                DB      "-", #C3                ; SUBTRACT
                DB      "*", #C4                ; MULTIPLY
                DB      "/", #C5                ; DIVISION
                DB      "^", #C6                ; TO_POWER
                DB      "=", #CE                ; NOS_EQL
                DB      ">", #CC                ; NO_GRTR
                DB      "<", #CD                ; NO_LESS
                DB      #C7, #C9                ; NO_L_EQL '<='
                DB      #C8, #CA                ; NO_GR_EQL '>='
                DB      #C9, #CB                ; NOS_NEQL '<>'
                DB      #C5, #C7                ; OR
                DB      #C6, #C8                ; AND
                DB      #00                     ; End marker

; Table of priorities
TBL_PRIORS:     DB      #06                     ; '-'
                DB      #08                     ; '*'
                DB      #08                     ; '/'
                DB      #0A                     ; '^'
                DB      #02                     ; OR
                DB      #03                     ; AND
                DB      #05                     ; '<='
                DB      #05                     ; '>='
                DB      #05                     ; '<>'
                DB      #05                     ; '>'
                DB      #05                     ; '<'
                DB      #05                     ; '='
                DB      #06                     ; '+'

; User defined functions handling
S_FN_SBRN:      CALL    SYNTAX_Z
                JR      NZ,SF_RUN
                RST     #20
                CALL    ALPHA
                JP      NC,REPORT_C
                RST     #20
                CP      #24
                PUSH    AF
                JR      NZ,SF_BRKT_1
                RST     #20
SF_BRKT_1:      CP      #28
                JR      NZ,SF_RPRT_C
                RST     #20
                CP      #29
                JR      Z,SF_FLAG_6
SF_ARGMTS:      CALL    SCANNING
                RST     #18
                CP      #2C
                JR      NZ,SF_BRKT_2
                RST     #20
                JR      SF_ARGMTS

SF_BRKT_2:      CP      #29
SF_RPRT_C:      JP      NZ,REPORT_C
SF_FLAG_6:      RST     #20
                LD      HL,#5C3B
                RES     6,(HL)
                POP     AF
                JR      Z,SF_SYN_EN
                SET     6,(HL)
SF_SYN_EN       JP      S_CONT_2

SF_RUN:         RST     #20
                AND     #DF
                LD      B,A
                RST     #20
                SUB     #24
                LD      C,A
                JR      NZ,SF_ARGMT1
                RST     #20
SF_ARGMT1:      RST     #20
                PUSH    HL
                LD      HL,(#5C53)
                DEC     HL
SF_FND_DF:      LD      DE,#00CE
                PUSH    BC
                CALL    LOOK_PROG
                POP     BC
                JR      NC,SF_CP_DEF
REPORT_P:       RST     #08                     ; Error report
                DB      #18                     ; FN without DEF
SF_CP_DEF:      PUSH    HL
                CALL    FN_SKPOVR
                AND     #DF
                CP      B
                JR      NZ,SF_NOT_FD
                CALL    FN_SKPOVR
                SUB     #24
                CP      C
                JR      Z,SF_VALUES
SF_NOT_FD:      POP     HL
                DEC     HL
                LD      DE,#0200
                PUSH    BC
                CALL    EACH_STMT
                POP     BC
                JR      SF_FND_DF

SF_VALUES:      AND     A
                CALL    Z,FN_SKPOVR
                POP     DE
                POP     DE
                LD      (#5C5D),DE
                CALL    FN_SKPOVR
                PUSH    HL
                CP      #29
                JR      Z,SF_R_BR_2
SF_ARG_LP:      INC     HL
                LD      A,(HL)
                CP      #0E
                LD      D,#40
                JR      Z,SF_ARG_VR
                DEC     HL
                CALL    FN_SKPOVR
                INC     HL
                LD      D,#00
SF_ARG_VR:      INC     HL
                PUSH    HL
                PUSH    DE
                CALL    SCANNING
                POP     AF
                XOR     (IY+#01)
                AND     #40
                JR      NZ,REPORT_Q
                POP     HL
                EX      DE,HL
                LD      HL,(#5C65)
                LD      BC,#0005
                SBC     HL,BC
                LD      (#5C65),HL
                LDIR
                EX      DE,HL
                DEC     HL
                CALL    FN_SKPOVR
                CP      #29
                JR      Z,SF_R_BR_2
                PUSH    HL
                RST     #18
                CP      #2C
                JR      NZ,REPORT_Q
                RST     #20
                POP     HL
                CALL    FN_SKPOVR
                JR      SF_ARG_LP

SF_R_BR_2:      PUSH    HL
                RST     #18
                CP      #29
                JR      Z,SF_VALUE
REPORT_Q:       RST     #08                     ; Error report
                DB      #19                     ; Parameter error
SF_VALUE:       POP     DE
                EX      DE,HL
                LD      (#5C5D),HL
                LD      HL,(#5C0B)
                EX      (SP),HL
                LD      (#5C0B),HL
                PUSH    DE
                RST     #20
                RST     #20
                CALL    SCANNING
                POP     HL
                LD      (#5C5D),HL
                POP     HL
                LD      (#5C0B),HL
                RST     #20
                JP      S_CONT_2

; Skip spaces and color control codes in DEF FN
FN_SKPOVR:      INC     HL
                LD      A,(HL)
                CP      #21
                JR      C,FN_SKPOVR
                RET

; Variables lookup
LOOK_VARS:      SET     6,(IY+#01)
                RST     #18
                CALL    ALPHA
                JP      NC,REPORT_C
                PUSH    HL
                AND     #1F
                LD      C,A
                RST     #20
                PUSH    HL
                CP      #28
                JR      Z,V_RUN_SYN
                SET     6,C
                CP      #24
                JR      Z,V_STR_VAR
                SET     5,C
                CALL    ALPHANUM
                JR      NC,V_TEST_FN
V_CHAR:         CALL    ALPHANUM
                JR      NC,V_RUN_SYN
                RES     6,C
                RST     #20
                JR      V_CHAR

V_STR_VAR:      RST     #20
                RES     6,(IY+#01)
V_TEST_FN:      LD      A,(#5C0C)
                AND     A
                JR      Z,V_RUN_SYN
                CALL    SYNTAX_Z
                JP      NZ,STK_F_ARG
V_RUN_SYN:      LD      B,C
                CALL    SYNTAX_Z
                JR      NZ,V_RUN
                LD      A,C
                AND     #E0
                SET     7,A
                LD      C,A
                JR      V_SYNTAX

V_RUN:          LD      HL,(#5C4B)
V_EACH:         LD      A,(HL)
                AND     #7F
                JR      Z,V_80_BYTE
                CP      C
                JR      NZ,V_NEXT
                RLA
                ADD     A,A
                JP      P,V_FOUND_2
                JR      C,V_FOUND_2
                POP     DE
                PUSH    DE
                PUSH    HL
V_MATCHES:      INC     HL
V_SPACES:       LD      A,(DE)
                INC     DE
                CP      #20
                JR      Z,V_SPACES
                OR      #20
                CP      (HL)
                JR      Z,V_MATCHES
                OR      #80
                CP      (HL)
                JR      NZ,V_GET_PTR
                LD      A,(DE)
                CALL    ALPHANUM
                JR      NC,V_FOUND_1
V_GET_PTR:      POP     HL
V_NEXT:         PUSH    BC
                CALL    NEXT_ONE
                EX      DE,HL
                POP     BC
                JR      V_EACH

V_80_BYTE:      SET     7,B
V_SYNTAX:       POP     DE
                RST     #18
                CP      #28
                JR      Z,V_PASS
                SET     5,B
                JR      V_END

V_FOUND_1:      POP     DE
V_FOUND_2:      POP     DE
                POP     DE
                PUSH    HL
                RST     #18
V_PASS:         CALL    ALPHANUM
                JR      NC,V_END
                RST     #20
                JR      V_PASS

V_END:          POP     HL
                RL      B
                BIT     6,B
                RET

; Stack function argument
STK_F_ARG:      LD      HL,(#5C0B)
                LD      A,(HL)
                CP      #29
                JP      Z,V_RUN_SYN
SFA_LOOP:       LD      A,(HL)
                OR      #60
                LD      B,A
                INC     HL
                LD      A,(HL)
                CP      #0E
                JR      Z,SFA_CP_VR
                DEC     HL
                CALL    FN_SKPOVR
                INC     HL
                RES     5,B
SFA_CP_VR:      LD      A,B
                CP      C
                JR      Z,SFA_MATCH
                INC     HL
                INC     HL
                INC     HL
                INC     HL
                INC     HL
                CALL    FN_SKPOVR
                CP      #29
                JP      Z,V_RUN_SYN
                CALL    FN_SKPOVR
                JR      SFA_LOOP

SFA_MATCH:      BIT     5,C
                JR      NZ,SFA_END
                INC     HL
                LD      DE,(#5C65)
                CALL    MOVE_FP
                EX      DE,HL
                LD      (#5C65),HL
SFA_END:        POP     DE
                POP     DE
                XOR     A
                INC     A
                RET

; Stack variable component
STK_VAR:        XOR     A
                LD      B,A
                BIT     7,C
                JR      NZ,SV_COUNT
                BIT     7,(HL)
                JR      NZ,SV_ARRAYS
                INC     A
SV_SIMPLE:      INC     HL
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                INC     HL
                EX      DE,HL
                CALL    STK_STO_D
                RST     #18
                JP      SV_SLICE_EX

SV_ARRAYS:      INC     HL
                INC     HL
                INC     HL
                LD      B,(HL)
                BIT     6,C
                JR      Z,SV_PTR
                DEC     B
                JR      Z,SV_SIMPLE
                EX      DE,HL
                RST     #18
                CP      #28
                JR      NZ,REPORT_3
                EX      DE,HL
SV_PTR:         EX      DE,HL
                JR      SV_COUNT

SV_COMMA:       PUSH    HL
                RST     #18
                POP     HL
                CP      #2C
                JR      Z,SV_LOOP
                BIT     7,C
                JR      Z,REPORT_3
                BIT     6,C
                JR      NZ,SV_CLOSE
                CP      #29
                JR      NZ,SV_RPT_C
                RST     #20
                RET

SV_CLOSE:       CP      #29
                JR      Z,SV_DIM
                CP      #CC
                JR      NZ,SV_RPT_C
SV_CH_ADD:      RST     #18
                DEC     HL
                LD      (#5C5D),HL
                JR      SV_SLICE

SV_COUNT:       LD      HL,#0000
SV_LOOP:        PUSH    HL
                RST     #20
                POP     HL
                LD      A,C
                CP      #C0
                JR      NZ,SV_MULT
                RST     #18
                CP      #29
                JR      Z,SV_DIM
                CP      #CC
                JR      Z,SV_CH_ADD
SV_MULT:        PUSH    BC
                PUSH    HL
                CALL    DE_DE_1
                EX      (SP),HL
                EX      DE,HL
                CALL    INT_EXP1
                JR      C,REPORT_3
                DEC     BC
                CALL    GET_HL_DE
                ADD     HL,BC
                POP     DE
                POP     BC
                DJNZ    SV_COMMA
                BIT     7,C
SV_RPT_C:       JR      NZ,SL_RPT_C
                PUSH    HL
                BIT     6,C
                JR      NZ,SV_ELEM
                LD      B,D
                LD      C,E
                RST     #18
                CP      #29
                JR      Z,SV_NUMBER
REPORT_3:       RST     #08                     ; Error report
                DB      #02                     ; Subscript wrong
SV_NUMBER:      RST     #20
                POP     HL
                LD      DE,#0005
                CALL    GET_HL_DE
                ADD     HL,BC
                RET

SV_ELEM:        CALL    DE_DE_1
                EX      (SP),HL
                CALL    GET_HL_DE
                POP     BC
                ADD     HL,BC
                INC     HL
                LD      B,D
                LD      C,E
                EX      DE,HL
                CALL    STK_ST_0
                RST     #18
                CP      #29
                JR      Z,SV_DIM
                CP      #2C
                JR      NZ,REPORT_3
SV_SLICE:       CALL    SLICING
SV_DIM:         RST     #20
SV_SLICE_EX:    CP      #28
                JR      Z,SV_SLICE
                RES     6,(IY+#01)
                RET

; Handle slicing of strings
SLICING:        CALL    SYNTAX_Z
                CALL    NZ,STK_FETCH
                RST     #20
                CP      #29
                JR      Z,SL_STORE
                PUSH    DE
                XOR     A
                PUSH    AF
                PUSH    BC
                LD      DE,#0001
                RST     #18
                POP     HL
                CP      #CC
                JR      Z,SL_SECOND
                POP     AF
                CALL    INT_EXP2
                PUSH    AF
                LD      D,B
                LD      E,C
                PUSH    HL
                RST     #18
                POP     HL
                CP      #CC
                JR      Z,SL_SECOND
                CP      #29
SL_RPT_C:       JP      NZ,REPORT_C
                LD      H,D
                LD      L,E
                JR      SL_DEFINE

SL_SECOND:      PUSH    HL
                RST     #20
                POP     HL
                CP      #29
                JR      Z,SL_DEFINE
                POP     AF
                CALL    INT_EXP2
                PUSH    AF
                RST     #18
                LD      H,B
                LD      L,C
                CP      #29
                JR      NZ,SL_RPT_C
SL_DEFINE:      POP     AF
                EX      (SP),HL
                ADD     HL,DE
                DEC     HL
                EX      (SP),HL
                AND     A
                SBC     HL,DE
                LD      BC,#0000
                JR      C,SL_OVER
                INC     HL
                AND     A
                JP      M,REPORT_3
                LD      B,H
                LD      C,L
SL_OVER:        POP     DE
SL_OVER1:       RES     6,(IY+#01)
SL_STORE:       CALL    SYNTAX_Z
                RET     Z
STK_ST_0:       XOR     A
STK_STO_D:      RES     6,(IY+#01)
STK_STORE:      PUSH    BC                      ; Put five registers on the calc stack
                CALL    TEST_5_SP
                POP     BC
                LD      HL,(#5C65)
                LD      (HL),A
                INC     HL
                LD      (HL),E
                INC     HL
                LD      (HL),D
                INC     HL
                LD      (HL),C
                INC     HL
                LD      (HL),B
                INC     HL
                LD      (#5C65),HL
                RET

; Check and evaluate an integer expression
INT_EXP1:       XOR     A
INT_EXP2:       PUSH    DE
                PUSH    HL
                PUSH    AF
                CALL    EXPT_1NUM
                POP     AF
                CALL    SYNTAX_Z
                JR      Z,I_RESTORE
                PUSH    AF
                CALL    FIND_INT2
                POP     DE
                LD      A,B
                OR      C
                SCF
                JR      Z,I_CARRY
                POP     HL
                PUSH    HL
                AND     A
                SBC     HL,BC
I_CARRY:        LD      A,D
                SBC     A,#00
I_RESTORE:      POP     HL
                POP     DE
                RET

; Load DE+1 into DE
DE_DE_1:        EX      DE,HL
                INC     HL
                LD      E,(HL)
                INC     HL
                LD      D,(HL)
                RET

; Multiply HL by DE
GET_HL_DE:      CALL    SYNTAX_Z
                RET     Z
                CALL    HL_HL_DE
                JP      C,REPORT_4
                RET

; Handle LET command
LET:            LD      HL,(#5C4D)
                BIT     1,(IY+#37)
                JR      Z,L_EXISTS
                LD      BC,#0005
L_EACH_CH:      INC     BC
L_NO_SP:        INC     HL
                LD      A,(HL)
                CP      #20
                JR      Z,L_NO_SP
                JR      NC,L_TEST_CH
                CP      #10
                JR      C,L_SPACES
                CP      #16
                JR      NC,L_SPACES
                INC     HL
                JR      L_NO_SP

L_TEST_CH:      CALL    ALPHANUM
                JR      C,L_EACH_CH
                CP      #24
                JP      Z,L_NEW
L_SPACES:       LD      A,C
                LD      HL,(#5C59)
                DEC     HL
                CALL    MAKE_ROOM
                INC     HL
                INC     HL
                EX      DE,HL
                PUSH    DE
                LD      HL,(#5C4D)
                DEC     DE
                SUB     #06
                LD      B,A
                JR      Z,L_SINGLE
L_CHAR:         INC     HL
                LD      A,(HL)
                CP      #21
                JR      C,L_CHAR
                OR      #20
                INC     DE
                LD      (DE),A
                DJNZ    L_CHAR
                OR      #80
                LD      (DE),A
                LD      A,#C0
L_SINGLE:       LD      HL,(#5C4D)
                XOR     (HL)
                OR      #20
                POP     HL
                CALL    L_FIRST
L_NUMERIC:      PUSH    HL
                RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                POP     HL
                LD      BC,#0005
                AND     A
                SBC     HL,BC
                JR      L_ENTER

L_EXISTS:       BIT     6,(IY+#01)
                JR      Z,L_DELETE
                LD      DE,#0006
                ADD     HL,DE
                JR      L_NUMERIC

L_DELETE:       LD      HL,(#5C4D)
                LD      BC,(#5C72)
                BIT     0,(IY+#37)
                JR      NZ,L_ADD
                LD      A,B
                OR      C
                RET     Z
                PUSH    HL
                RST     #30
                PUSH    DE
                PUSH    BC
                LD      D,H
                LD      E,L
                INC     HL
                LD      (HL),#20
                LDDR
                PUSH    HL
                CALL    STK_FETCH
                POP     HL
                EX      (SP),HL
                AND     A
                SBC     HL,BC
                ADD     HL,BC
                JR      NC,L_LENGTH
                LD      B,H
                LD      C,L
L_LENGTH:       EX      (SP),HL
                EX      DE,HL
                LD      A,B
                OR      C
                JR      Z,L_IN_W_S
                LDIR
L_IN_W_S:       POP     BC
                POP     DE
                POP     HL
L_ENTER:        EX      DE,HL
                LD      A,B
                OR      C
                RET     Z
                PUSH    DE
                LDIR
                POP     HL
                RET

L_ADD:          DEC     HL
                DEC     HL
                DEC     HL
                LD      A,(HL)
                PUSH    HL
                PUSH    BC
                CALL    L_STRING
                POP     BC
                POP     HL
                INC     BC
                INC     BC
                INC     BC
                JP      RECLAIM_2

L_NEW:          LD      A,#DF
                LD      HL,(#5C4D)
                AND     (HL)
L_STRING:       PUSH    AF
                CALL    STK_FETCH
                EX      DE,HL
                ADD     HL,BC
                PUSH    BC
                DEC     HL
                LD      (#5C4D),HL
                INC     BC
                INC     BC
                INC     BC
                LD      HL,(#5C59)
                DEC     HL
                CALL    MAKE_ROOM
                LD      HL,(#5C4D)
                POP     BC
                PUSH    BC
                INC     BC
                LDDR
                EX      DE,HL
                INC     HL
                POP     BC
                LD      (HL),B
                DEC     HL
                LD      (HL),C
                POP     AF
L_FIRST:        DEC     HL
                LD      (HL),A
                LD      HL,(#5C59)
                DEC     HL
                RET

; Get last value from the calc stack
STK_FETCH:      LD      HL,(#5C65)
                DEC     HL
                LD      B,(HL)
                DEC     HL
                LD      C,(HL)
                DEC     HL
                LD      D,(HL)
                DEC     HL
                LD      E,(HL)
                DEC     HL
                LD      A,(HL)
                LD      (#5C65),HL
                RET

; Handle DIM command
DIM:            CALL    LOOK_VARS
D_RPORT_C:      JP      NZ,REPORT_C
                CALL    SYNTAX_Z
                JR      NZ,D_RUN
                RES     6,C
                CALL    STK_VAR
                CALL    CHECK_END
D_RUN:          JR      C,D_LETTER
                PUSH    BC
                CALL    NEXT_ONE
                CALL    RECLAIM_2
                POP     BC
D_LETTER:       SET     7,C
                LD      B,#00
                PUSH    BC
                LD      HL,#0001
                BIT     6,C
                JR      NZ,D_SIZE
                LD      L,#05
D_SIZE:         EX      DE,HL
D_NO_LOOP:      RST     #20
                LD      H,#FF
                CALL    INT_EXP1
                JP      C,REPORT_3
                POP     HL
                PUSH    BC
                INC     H
                PUSH    HL
                LD      H,B
                LD      L,C
                CALL    GET_HL_DE
                EX      DE,HL
                RST     #18
                CP      #2C
                JR      Z,D_NO_LOOP
                CP      #29
                JR      NZ,D_RPORT_C
                RST     #20
                POP     BC
                LD      A,C
                LD      L,B
                LD      H,#00
                INC     HL
                INC     HL
                ADD     HL,HL
                ADD     HL,DE
                JP      C,REPORT_4
                PUSH    DE
                PUSH    BC
                PUSH    HL
                LD      B,H
                LD      C,L
                LD      HL,(#5C59)
                DEC     HL
                CALL    MAKE_ROOM
                INC     HL
                LD      (HL),A
                POP     BC
                DEC     BC
                DEC     BC
                DEC     BC
                INC     HL
                LD      (HL),C
                INC     HL
                LD      (HL),B
                POP     BC
                LD      A,B
                INC     HL
                LD      (HL),A
                LD      H,D
                LD      L,E
                DEC     DE
                LD      (HL),#00
                BIT     6,C
                JR      Z,DIM_CLEAR
                LD      (HL),#20
DIM_CLEAR:      POP     BC
                LDDR
DIM_SIZES:      POP     BC
                LD      (HL),B
                DEC     HL
                LD      (HL),C
                DEC     HL
                DEC     A
                JR      NZ,DIM_SIZES
                RET

; Check that the character in A is alphanumeric
ALPHANUM:       CALL    NUMERIC
                CCF
                RET     C
ALPHA:          CP      #41
                CCF
                RET     NC
                CP      #5B
                RET     C
                CP      #61
                CCF
                RET     NC
                CP      #7B
                RET

; Decimal to floating point
DEC_TO_FP:      CP      #C4
                JR      NZ,NOT_BIN
                LD      DE,#0000
BIN_DIGIT:      RST     #20
                SUB     #31
                ADC     A,#00
                JR      NZ,BIN_END
                EX      DE,HL
                CCF
                ADC     HL,HL
                JP      C,REPORT_6
                EX      DE,HL
                JR      BIN_DIGIT

BIN_END:        LD      B,D
                LD      C,E
                JP      STACK_BC

NOT_BIN:        CP      #2E
                JR      Z,DECIMAL
                CALL    INT_TO_FP
                CP      #2E
                JR      NZ,E_FORMAT
                RST     #20
                CALL    NUMERIC
                JR      C,E_FORMAT
                JR      DEC_STO_1

DECIMAL:        RST     #20
                CALL    NUMERIC
DEC_RPT_C:      JP      C,REPORT_C
                RST     #28                     ;FP_CALC
                DB      #A0                     ;STK_ZERO
                DB      #38                     ;END_CALC

DEC_STO_1:      RST     #28                     ;FP_CALC
                DB      #A1                     ;STK_ONE
                DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC

NXT_DGT_1:      RST     #18
                CALL    STK_DIGIT
                JR      C,E_FORMAT
                RST     #28                     ;FP_CALC
                DB      #E0                     ;GET_MEM_0
                DB      #A4                     ;STK_TEN
                DB      #05                     ;DIVISION
                DB      #C0                     ;ST_MEM_0
                DB      #04                     ;MULTIPLY
                DB      #0F                     ;ADDITION
                DB      #38                     ;END_CALC
                RST     #20
                JR      NXT_DGT_1

E_FORMAT:       CP      #45
                JR      Z,SIGN_FLAG
                CP      #65
                RET     NZ
SIGN_FLAG:      LD      B,#FF
                RST     #20
                CP      #2B
                JR      Z,SIGN_DONE
                CP      #2D
                JR      NZ,ST_E_PART
                INC     B
SIGN_DONE:      RST     #20
ST_E_PART:      CALL    NUMERIC
                JR      C,DEC_RPT_C
                PUSH    BC
                CALL    INT_TO_FP
                CALL    FP_TO_A
                POP     BC
                JP      C,REPORT_6
                AND     A
                JP      M,REPORT_6
                INC     B
                JR      Z,E_FP_JUMP
                NEG
E_FP_JUMP:      JP      E_TO_FP

; Check for valid digit
NUMERIC:        CP      #30
                RET     C
                CP      #3A
                CCF
                RET

; Stack digit
STK_DIGIT:      CALL    NUMERIC
                RET     C
                SUB     #30
STACK_A:        LD      C,A                     ;Stack accumulator
                LD      B,#00
STACK_BC:       LD      IY,#5C3A                ;Stack BC register pair
                XOR     A
                LD      E,A
                LD      D,C
                LD      C,B
                LD      B,A
                CALL    STK_STORE
                RST     #28                     ;FP_CALC
                DB      #38                     ;END_CALC
                AND     A
                RET

; Integer to floating point
INT_TO_FP:      PUSH    AF
                RST     #28                     ;FP_CALC
                DB      #A0                     ;STK_ZERO
                DB      #38                     ;END_CALC
                POP     AF
NXT_DGT_2:      CALL    STK_DIGIT
                RET     C
                RST     #28                     ;FP_CALC
                DB      #01                     ;EXCHANGE
                DB      #A4                     ;STK_TEN
                DB      #04                     ;MULTIPLY
                DB      #0F                     ;ADDITION
                DB      #38                     ;END_CALC
                CALL    CH_ADD_1
                JR      NXT_DGT_2

; E-format to floating point
E_TO_FP:        RLCA
                RRCA
                JR      NC,E_SAVE
                CPL
                INC     A
E_SAVE:         PUSH    AF
                LD      HL,#5C92
                CALL    FP_0_1
                RST     #28                     ;FP_CALC
                DB      #A4                     ;STK_TEN
                DB      #38                     ;END_CALC
                POP     AF
E_LOOP:         SRL     A
                JR      NC,E_TST_END
                PUSH    AF
                RST     #28                     ;FP_CALC
                DB      #C1                     ;ST_MEM_1
                DB      #E0                     ;GET_MEM_0
                DB      #00                     ;JUMP_TRUE
                DB      #04                     ;to E_DIVSN
                DB      #04                     ;MULTIPLY
                DB      #33                     ;JUMP
                DB      #02                     ;to E_FETCH
E_DIVSN:        DB      #05                     ;DIVISION
E_FETCH:        DB      #E1                     ;GET_MEM_1
                DB      #38                     ;END_CALC
                POP     AF
E_TST_END:      JR      Z,E_END
                PUSH    AF
                RST     #28                     ;FP_CALC
                DB      #31                     ;DUPLICATE
                DB      #04                     ;MULTIPLY
                DB      #38                     ;END_CALC
                POP     AF
                JR      E_LOOP

E_END:          RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                RET

; Fetch integer
INT_FETCH:      INC     HL
                LD      C,(HL)
                INC     HL
                LD      A,(HL)
                XOR     C
                SUB     C
                LD      E,A
                INC     HL
                LD      A,(HL)
                ADC     A,C
                XOR     C
                LD      D,A
                RET

; Store a positive integer. Not used in ROM.
P_INT_STO:      LD      C,#00

; Store an integer
INT_STORE:      PUSH    HL
                LD      (HL),#00
                INC     HL
                LD      (HL),C
                INC     HL
                LD      A,E
                XOR     C
                SUB     C
                LD      (HL),A
                INC     HL
                LD      A,D
                ADC     A,C
                XOR     C
                LD      (HL),A
                INC     HL
                LD      (HL),#00
                POP     HL
                RET

; Get floating point number from the calc stack to the BC
FP_TO_BC:       RST     #28                     ;FP_CALC
                DB      #38                     ;END_CALCS
                LD      A,(HL)
                AND     A
                JR      Z,FP_DELETE
                RST     #28                     ;FP_CALC
                DB      #A2                     ;STK_HALF
                DB      #0F                     ;ADDITION
                DB      #27                     ;INT
                DB      #38                     ;END_CALC

FP_DELETE:      RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                PUSH    HL
                PUSH    DE
                EX      DE,HL
                LD      B,(HL)
                CALL    INT_FETCH
                XOR     A
                SUB     B
                BIT     7,C
                LD      B,D
                LD      C,E
                LD      A,E
                POP     DE
                POP     HL
                RET

LOG_2_A:        LD      D,A
                RLA
                SBC     A,A
                LD      E,A
                LD      C,A
                XOR     A
                LD      B,A
                CALL    STK_STORE
                RST     #28                     ;FP_CALC
                DB      #34                     ;STK_DATA
                DB      #EF                     ;Exponent
                DB      #1A                     ;
                DB      #20                     ;
                DB      #9A                     ;
                DB      #85                     ;
                DB      #04                     ;MULTIPLY
                DB      #27                     ;INT
                DB      #38                     ;END_CALC

; Floating point to A
FP_TO_A:        CALL    FP_TO_BC
                RET     C
                PUSH    AF
                DEC     B
                INC     B
                JR      Z,FP_A_END
                POP     AF
                SCF
                RET

FP_A_END:       POP     AF
                RET

; Print a floating point number
PRINT_FP:       RST     #28             ;FP_CALC
                DB      #31             ;DUPLICATE
                DB      #36             ;LESS_0
                DB      #00             ;JUMP_TRUE
                DB      #0B             ;to PF_NEGTVE
                DB      #31             ;DUPLICATE
                DB      #37             ;GREATER_0
                DB      #00             ;JUMP_TRUE
                DB      #0D             ;to PS_POSTVE
                DB      #02             ;DELETE
                DB      #38             ;END_CALC
                LD      A,#30
                RST     #10
                RET

PF_NEGTVE:      DB      #2A             ;ABS
                DB      #38             ;END_CALC
                LD      A,#2D
                RST     #10
                RST     #28             ;FP_CALC
PF_POSTVE:      DB      #A0             ;STK_ZERO
                DB      #C3             ;ST_MEM_3
                DB      #C4             ;ST_MEM_4
                DB      #C5             ;ST_MEM_5
                DB      #02             ;DELETE
                DB      #38             ;END_CALC
                EXX
                PUSH    HL
                EXX
PF_LOOP:        RST     #28             ;FP_CALC
                DB      #31             ;DUPLICATE
                DB      #27             ;INT
                DB      #C2             ;ST_MEM_2
                DB      #03             ;SUBTRACT
                DB      #E2             ;GET_MEM_2
                DB      #01             ;EXCHANGE
                DB      #C2             ;ST_MEM_2
                DB      #02             ;DELETE
                DB      #38             ;END_CALC
                LD      A,(HL)
                AND     A
                JR      NZ,PF_LARGE
                CALL    INT_FETCH
                LD      B,#10
                LD      A,D
                AND     A
                JR      NZ,PF_SAVE
                OR      E
                JR      Z,PF_SMALL
                LD      D,E
                LD      B,#08
PF_SAVE:        PUSH    DE
                EXX
                POP     DE
                EXX
                JR      PF_BITS

PF_SMALL:       RST     #28             ;FP_CALC
                DB      #E2             ;GET_MEM_2
                DB      #38             ;END_CALC
                LD      A,(HL)
                SUB     #7E
                CALL    LOG_2_A
                LD      D,A
                LD      A,(#5CAC)
                SUB     D
                LD      (#5CAC),A
                LD      A,D
                CALL    E_TO_FP
                RST     #28             ;FP_CALC
                DB      #31             ;DUPLICATE
                DB      #27             ;21
                DB      #C1             ;ST_MEM_1
                DB      #03             ;SUBTRACT
                DB      #E1             ;GET_MEM_1
                DB      #38             ;END_CALC
                CALL    FP_TO_A
                PUSH    HL
                LD      (#5CA1),A
                DEC     A
                RLA
                SBC     A,A
                INC     A
                LD      HL,#5CAB
                LD      (HL),A
                INC     HL
                ADD     A,(HL)
                LD      (HL),A
                POP     HL
                JP      PF_FRACTN

PF_LARGE:       SUB     #80
                CP      #1C
                JR      C,PF_MEDIUM
                CALL    LOG_2_A
                SUB     #07
                LD      B,A
                LD      HL,#5CAC
                ADD     A,(HL)
                LD      (HL),A
                LD      A,B
                NEG
                CALL    E_TO_FP
                JR      PF_LOOP

PF_MEDIUM:      EX      DE,HL
                CALL    FETCH_TWO
                EXX
                SET     7,D
                LD      A,L
                EXX
                SUB     #80
                LD      B,A
PF_BITS:        SLA     E
                RL      D
                EXX
                RL      E
                RL      D
                EXX
                LD      HL,#5CAA
                LD      C,#05
PF_BYTES:       LD      A,(HL)
                ADC     A,A
                DAA
                LD      (HL),A
                DEC     HL
                DEC     C
                JR      NZ,PF_BYTES
                DJNZ    PF_BITS
                XOR     A
                LD      HL,#5CA6
                LD      DE,#5CA1
                LD      B,#09
                RLD
                LD      C,#FF
PF_DIGITS:      RLD
                JR      NZ,PF_INSERT
                DEC     C
                INC     C
                JR      NZ,PF_TEST_2
PF_INSERT:      LD      (DE),A
                INC     DE
                INC     (IY+#71)
                INC     (IY+#72)
                LD      C,#00
PF_TEST_2:      BIT     0,B
                JR      Z,PF_ALL_9
                INC     HL
PF_ALL_9:       DJNZ    PF_DIGITS
                LD      A,(#5CAB)
                SUB     #09
                JR      C,PF_MORE
                DEC     (IY+#71)
                LD      A,#04
                CP      (IY+#6F)
                JR      PF_ROUND

PF_MORE:        RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #E2                     ;GET_MEM_2
                DB      #38                     ;END_CALC

PF_FRACTN:      EX      DE,HL
                CALL    FETCH_TWO
                EXX
                LD      A,#80
                SUB     L
                LD      L,#00
                SET     7,D
                EXX
                CALL    SHIFT_FP
PF_FRN_LP:      LD      A,(IY+#71)
                CP      #08
                JR      C,PF_FR_DGT
                EXX
                RL      D
                EXX
                JR      PF_ROUND

PF_FR_DGT:      LD      BC,#0200
PF_FR_EXX:      LD      A,E
                CALL    CA_10_A_C
                LD      E,A
                LD      A,D
                CALL    CA_10_A_C
                LD      D,A
                PUSH    BC
                EXX
                POP     BC
                DJNZ    PF_FR_EXX
                LD      HL,#5CA1
                LD      A,C
                LD      C,(IY+#71)
                ADD     HL,BC
                LD      (HL),A
                INC     (IY+#71)
                JR      PF_FRN_LP

PF_ROUND:       PUSH    AF
                LD      HL,#5CA1
                LD      C,(IY+#71)
                LD      B,#00
                ADD     HL,BC
                LD      B,C
                POP     AF
PF_RND_LP:      DEC     HL
                LD      A,(HL)
                ADC     A,#00
                LD      (HL),A
                AND     A
                JR      Z,PF_R_BACK
                CP      #0A
                CCF
                JR      NC,PF_COUNT
PF_R_BACK:      DJNZ    PF_RND_LP
                LD      (HL),#01
                INC     B
                INC     (IY+#72)
PF_COUNT:       LD      (IY+#71),B
                RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                EXX
                POP     HL
                EXX
                LD      BC,(#5CAB)
                LD      HL,#5CA1
                LD      A,B
                CP      #09
                JR      C,PF_NOT_E
                CP      #FC
                JR      C,PF_E_FRMT
PF_NOT_E:       AND     A
                CALL    Z,OUT_CODE
PF_E_SBRN:      XOR     A
                SUB     B
                JP      M,PF_OUT_LP
                LD      B,A
                JR      PF_DC_OUT

PF_OUT_LP:      LD      A,C
                AND     A
                JR      Z,PF_OUT_DT
                LD      A,(HL)
                INC     HL
                DEC     C
PF_OUT_DT:      CALL    OUT_CODE
                DJNZ    PF_OUT_LP
PF_DC_OUT:      LD      A,C
                AND     A
                RET     Z
                INC     B
                LD      A,#2E
PF_DEC_0:       RST     #10
                LD      A,#30
                DJNZ    PF_DEC_0
                LD      B,C
                JR      PF_OUT_LP

PF_E_FRMT:      LD      D,B
                DEC     D
                LD      B,#01
                CALL    PF_E_SBRN
                LD      A,#45
                RST     #10
                LD      C,D
                LD      A,C
                AND     A
                JP      P,PF_E_POS
                NEG
                LD      C,A
                LD      A,#2D
                JR      PF_E_SIGN

PF_E_POS:       LD      A,#2B
PF_E_SIGN:      RST     #10
                LD      B,#00
                JP      OUT_NUM_1

; Handle printing of floating point
CA_10_A_C:      PUSH    DE
                LD      L,A
                LD      H,#00
                LD      E,L
                LD      D,H
                ADD     HL,HL
                ADD     HL,HL
                ADD     HL,DE
                ADD     HL,HL
                LD      E,C
                ADD     HL,DE
                LD      C,H
                LD      A,L
                POP     DE
                RET

; Prepare the two numbers for addition
PREP_ADD:       LD      A,(HL)
                LD      (HL),#00
                AND     A
                RET     Z
                INC     HL
                BIT     7,(HL)
                SET     7,(HL)
                DEC     HL
                RET     Z
                PUSH    BC
                LD      BC,#0005
                ADD     HL,BC
                LD      B,C
                LD      C,A
                SCF
NEG_BYTE:       DEC     HL
                LD      A,(HL)
                CPL
                ADC     A,#00
                LD      (HL),A
                DJNZ    NEG_BYTE
                LD      A,C
                POP     BC
                RET

; Fetch two numbers
FETCH_TWO:      PUSH    HL
                PUSH    AF
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                LD      (HL),A
                INC     HL
                LD      A,C
                LD      C,(HL)
                PUSH    BC
                INC     HL
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                EX      DE,HL
                LD      D,A
                LD      E,(HL)
                PUSH    DE
                INC     HL
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                PUSH    DE
                EXX
                POP     DE
                POP     HL
                POP     BC
                EXX
                INC     HL
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                POP     AF
                POP     HL
                RET

; Shift floating point numer to right
SHIFT_FP:       AND     A
                RET     Z
                CP      #21
                JR      NC,ADDEND_0
                PUSH    BC
                LD      B,A
ONE_SHIFT:      EXX
                SRA     L
                RR      D
                RR      E
                EXX
                RR      D
                RR      E
                DJNZ    ONE_SHIFT
                POP     BC
                RET     NC
                CALL    ADD_BACK
                RET     NZ
ADDEND_0:       EXX
                XOR     A
ZEROS_4_5:      LD      L,#00
                LD      D,A
                LD      E,L
                EXX
                LD      DE,#0000
                RET

; Add back any carry
ADD_BACK:       INC     E
                RET     NZ
                INC     D
                RET     NZ
                EXX
                INC     E
                JR      NZ,ALL_ADDED
                INC     D
ALL_ADDED:      EXX
                RET

; Handle subtraction
SUBTRACT:       EX      DE,HL
                CALL    NEGATE
                EX      DE,HL

; Handle Addition
ADDITION:       LD      A,(DE)
                OR      (HL)
                JR      NZ,FULL_ADDN
                PUSH    DE
                INC     HL
                PUSH    HL
                INC     HL
                LD      E,(HL)
                INC     HL
                LD      D,(HL)
                INC     HL
                INC     HL
                INC     HL
                LD      A,(HL)
                INC     HL
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                POP     HL
                EX      DE,HL
                ADD     HL,BC
                EX      DE,HL
                ADC     A,(HL)
                RRCA
                ADC     A,#00
                CALL    E65536
                LD      (HL),A
                INC     HL
                LD      (HL),E
                INC     HL
                LD      (HL),D
                DEC     HL
                DEC     HL
                DEC     HL
                POP     DE
                RET

ADDN_OFLW:      DEC     HL
                POP     DE
FULL_ADDN:      CALL    RE_ST_TWO
                EXX
                PUSH    HL
                EXX
                PUSH    DE
                PUSH    HL
                CALL    PREP_ADD
                LD      B,A
                EX      DE,HL
                CALL    PREP_ADD
                LD      C,A
                CP      B
                JR      NC,SHIFT_LEN
                LD      A,B
                LD      B,C
                EX      DE,HL
SHIFT_LEN:      PUSH    AF
                SUB     B
                CALL    FETCH_TWO
                CALL    SHIFT_FP
                POP     AF
                POP     HL
                LD      (HL),A
                PUSH    HL
                LD      L,B
                LD      H,C
                ADD     HL,DE
                EXX
                EX      DE,HL
                ADC     HL,BC
                EX      DE,HL
                LD      A,H
                ADC     A,L
                LD      L,A
                RRA
                XOR     L
                EXX
                EX      DE,HL
                POP     HL
                RRA
                JR      NC,TEST_NEG
                LD      A,#01
                CALL    SHIFT_FP
                INC     (HL)
                JR      Z,ADD_REP_6
TEST_NEG:       EXX
                LD      A,L
                AND     #80
                EXX
                INC     HL
                LD      (HL),A
                DEC     HL
                JR      Z,GO_NC_MLT
                LD      A,E
                NEG
                CCF
                LD      E,A
                LD      A,D
                CPL
                ADC     A,#00
                LD      D,A
                EXX
                LD      A,E
                CPL
                ADC     A,#00
                LD      E,A
                LD      A,D
                CPL
                ADC     A,#00
                JR      NC,END_COMPL
                RRA
                EXX
                INC     (HL)
ADD_REP_6:      JP      Z,REPORT_6
                EXX
END_COMPL:      LD      D,A
                EXX
GO_NC_MLT:      XOR     A
                JP      TEST_NORM

; HL - HL * DE
HL_HL_DE:       PUSH    BC
                LD      B,#10
                LD      A,H
                LD      C,L
                LD      HL,#0000
HL_LOOP:        ADD     HL,HL
                JR      C,HL_END
                RL      C
                RLA
                JR      NC,HL_AGAIN
                ADD     HL,DE
                JR      C,HL_END
HL_AGAIN:       DJNZ    HL_LOOP
HL_END:         POP     BC
                RET

; Prepare to multiply or divide
PREP_M_D:       CALL    TEST_ZERO
                RET     C
                INC     HL
                XOR     (HL)
                SET     7,(HL)
                DEC     HL
                RET

; Handle multiplication
MULTIPLY:       LD      A,(DE)
                OR      (HL)
                JR      NZ,MULT_LONG
                PUSH    DE
                PUSH    HL
                PUSH    DE
                CALL    INT_FETCH
                EX      DE,HL
                EX      (SP),HL
                LD      B,C
                CALL    INT_FETCH
                LD      A,B
                XOR     C
                LD      C,A
                POP     HL
                CALL    HL_HL_DE
                EX      DE,HL
                POP     HL
                JR      C,MULT_OFLW
                LD      A,D
                OR      E
                JR      NZ,MULT_RSLT
                LD      C,A
MULT_RSLT:      CALL    INT_STORE
                POP     DE
                RET

MULT_OFLW:      POP     DE
MULT_LONG:      CALL    RE_ST_TWO
                XOR     A
                CALL    PREP_M_D
                RET     C
                EXX
                PUSH    HL
                EXX
                PUSH    DE
                EX      DE,HL
                CALL    PREP_M_D
                EX      DE,HL
                JR      C,ZERO_RSLT
                PUSH    HL
                CALL    FETCH_TWO
                LD      A,B
                AND     A
                SBC     HL,HL
                EXX
                PUSH    HL
                SBC     HL,HL
                EXX
                LD      B,#21
                JR      STRT_MLT

MLT_LOOP:       JR      NC,NO_ADD
                ADD     HL,DE
                EXX
                ADC     HL,DE
                EXX
NO_ADD:         EXX
                RR      H
                RR      L
                EXX
                RR      H
                RR      L
STRT_MLT:       EXX
                RR      B
                RR      C
                EXX
                RR      C
                RRA
                DJNZ    MLT_LOOP
                EX      DE,HL
                EXX
                EX      DE,HL
                EXX
                POP     BC
                POP     HL
                LD      A,B
                ADD     A,C
                JR      NZ,MAKE_EXPT
                AND     A
MAKE_EXPT:      DEC     A
                CCF
DIVN_EXPT:      RLA
                CCF
                RRA
                JP      P,OFLW1_CLR
                JR      NC,REPORT_6
                AND     A
OFLW1_CLR:      INC     A
                JR      NZ,OFLW2_CLR
                JR      C,OFLW2_CLR
                EXX
                BIT     7,D
                EXX
                JR      NZ,REPORT_6
OFLW2_CLR       LD      (HL),A
                EXX
                LD      A,B
                EXX
TEST_NORM:      JR      NC,NORMALISE
                LD      A,(HL)
                AND     A
NEAR_ZERO:      LD      A,#80
                JR      Z,SKIP_ZERO
ZERO_RSLT:      XOR     A
SKIP_ZERO:      EXX
                AND     D
                CALL    ZEROS_4_5
                RLCA
                LD      (HL),A
                JR      C,OFLOW_CLR
                INC     HL
                LD      (HL),A
                DEC     HL
                JR      OFLOW_CLR

NORMALISE:      LD      B,#20
SHIFT_ONE:      EXX
                BIT     7,D
                EXX
                JR      NZ,NORML_NOW
                RLCA
                RL      E
                RL      D
                EXX
                RL      E
                RL      D
                EXX
                DEC     (HL)
                JR      Z,NEAR_ZERO
                DJNZ    SHIFT_ONE
                JR      ZERO_RSLT

NORML_NOW:      RLA
                JR      NC,OFLOW_CLR
                CALL    ADD_BACK
                JR      NZ,OFLOW_CLR
                EXX
                LD      D,#80
                EXX
                INC     (HL)
                JR      Z,REPORT_6
OFLOW_CLR:      PUSH    HL
                INC     HL
                EXX
                PUSH    DE
                EXX
                POP     BC
                LD      A,B
                RLA
                RL      (HL)
                RRA
                LD      (HL),A
                INC     HL
                LD      (HL),C
                INC     HL
                LD      (HL),D
                INC     HL
                LD      (HL),E
                POP     HL
                POP     DE
                EXX
                POP     HL
                EXX
                RET

REPORT_6:       RST     #08                     ; Error report
                DB      #05                     ; Number too big

; Handle division
DIVISION:       CALL    RE_ST_TWO
                EX      DE,HL
                XOR     A
                CALL    PREP_M_D
                JR      C,REPORT_6
                EX      DE,HL
                CALL    PREP_M_D
                RET     C
                EXX
                PUSH    HL
                EXX
                PUSH    DE
                PUSH    HL
                CALL    FETCH_TWO
                EXX
                PUSH    HL
                LD      H,B
                LD      L,C
                EXX
                LD      H,C
                LD      L,B
                XOR     A
                LD      B,#DF
                JR      DIV_START

DIV_LOOP:       RLA
                RL      C
                EXX
                RL      C
                RL      B
                EXX
DIV_34TH:       ADD     HL,HL
                EXX
                ADC     HL,HL
                EXX
                JR      C,SUBN_ONLY
DIV_START:      SBC     HL,DE
                EXX
                SBC     HL,DE
                EXX
                JR      NC,NO_RSTORE
                ADD     HL,DE
                EXX
                ADC     HL,DE
                EXX
                AND     A
                JR      COUNT_ONE

SUBN_ONLY:      AND     A
                SBC     HL,DE
                EXX
                SBC     HL,DE
                EXX
NO_RSTORE:      SCF
COUNT_ONE:      INC     B
                JP      M,DIV_LOOP
                PUSH    AF
                JR      Z,DIV_34TH              ; BSROM - bugfix - was DIV_START
                LD      E,A
                LD      D,C
                EXX
                LD      E,C
                LD      D,B
                POP     AF
                RR      B
                POP     AF
                RR      B
                EXX
                POP     BC
                POP     HL
                LD      A,B
                SUB     C
                JP      DIVN_EXPT

; Integer truncation towards zero
TRUNCATE:       LD      A,(HL)
                AND     A
                RET     Z
                CP      #81
                JR      NC,T_GR_ZERO            ; BSROM - bugfixed INT
                LD      (HL),#00
                LD      A,#20
                JR      NIL_BYTES

E65536:         JR      NZ,S65536
                SBC     A,A
                LD      C,A
                INC     A
                OR      D
                OR      E
                LD      A,C
                RET     NZ
S65536:         POP     AF
                JP      ADDN_OFLW

NEW_CHR:        CALL    FP_TO_A                 ; BSROM - bugfixed CHR$
                RET     C
                RET     Z
                POP     AF
                LD      DE,#0001
                LD      BC,#FFFF
                JP      CHR_DLR1

T_GR_ZERO:      CP      #91                     ; BSROM - modified INT
T_SMALL:        JR      NC,X_LARGE
                PUSH    DE
                CPL
                ADD     A,#91
                INC     HL
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                DEC     HL
                DEC     HL
                LD      C,#00
                BIT     7,D
                JR      Z,T_NUMERIC
                DEC     C
T_NUMERIC:      SET     7,D
                LD      B,#08
                SUB     B
                ADD     A,B
                JR      C,T_TEST
                LD      E,D
                LD      D,#00
                SUB     B
T_TEST:         JR      Z,T_STORE
                LD      B,A
T_SHIFT:        SRL     D
                RR      E
                DJNZ    T_SHIFT
T_STORE:        CALL    INT_STORE
                POP     DE
                RET

T_EXPNENT:      LD      A,(HL)
X_LARGE:        SUB     #A0
                RET     P
                NEG
NIL_BYTES:      PUSH    DE
                EX      DE,HL
                DEC     HL
                LD      B,A
                SRL     B
                SRL     B
                SRL     B
                JR      Z,BITS_ZERO
BYTE_ZERO:      LD      (HL),#00
                DEC     HL
                DJNZ    BYTE_ZERO
BITS_ZERO:      AND     #07
                JR      Z,IX_END
                LD      B,A
                LD      A,#FF
LESS_MASK:      SLA     A
                DJNZ    LESS_MASK
                AND     (HL)
                LD      (HL),A
IX_END:         EX      DE,HL
                POP     DE
                RET

; Re-stack two numbers in full floating point
RE_ST_TWO:      CALL    RESTK_SUB
RESTK_SUB:      EX      DE,HL

; Re-stack number in full form
RE_STACK:       LD      A,(HL)
                AND     A
                RET     NZ
                PUSH    DE
                CALL    INT_FETCH
                XOR     A
                INC     HL
                LD      (HL),A
                DEC     HL
                LD      (HL),A
                LD      B,#91
                LD      A,D
                AND     A
                JR      NZ,RS_NRMLSE
                OR      E
                LD      B,D
                JR      Z,RS_STORE
                LD      D,E
                LD      E,B
                LD      B,#89
RS_NRMLSE:      EX      DE,HL
RSTK_LOOP:      DEC     B
                ADD     HL,HL
                JR      NC,RSTK_LOOP
                RRC     C
                RR      H
                RR      L
                EX      DE,HL
RS_STORE:       DEC     HL
                LD      (HL),E
                DEC     HL
                LD      (HL),D
                DEC     HL
                LD      (HL),B
                POP     DE
                RET

; Floating point calculator
; Table of constants
STK_ZERO:       DB      #00
                DB      #B0
                DB      #00

STK_ONE:        DB      #40
                DB      #B0
                DB      #00
                DB      #01

STK_HALF:       DB      #30
                DB      #00
       
STK_PI_2:       DB      #F1
                DB      #49
                DB      #0F
                DB      #DA
                DB      #A2
       
STK_TEN:        DB      #40
                DB      #B0
                DB      #00
                DB      #0A

; Floating point calculator
; Table of addresses
TBL_ADDRS:      DW      JUMP_TRUE
                DW      EXCHANGE
                DW      DELETE
                DW      SUBTRACT
                DW      MULTIPLY
                DW      DIVISION
                DW      TO_POWER
                DW      OR_FUNC
                DW      NO_AND_NO
                DW      NO_L_EQL
                DW      NO_GR_EQL
                DW      NOS_NEQL
                DW      NO_GRTR
                DW      NO_LESS
                DW      NOS_EQL
                DW      ADDITION
                DW      STR_AND_NO
                DW      STR_L_EQL
                DW      STR_GR_EQL
                DW      STRS_NEQL
                DW      STR_GRTR
                DW      STR_LESS
                DW      STRS_EQL
                DW      STRS_ADD
                DW      VAL_DLR
                DW      USR_STR
                DW      READ_IN
                DW      NEGATE
                DW      CODE
                DW      VAL
                DW      LEN
                DW      SIN_FUNC
                DW      COS_FUNC
                DW      TAN_FUNC
                DW      ASN_FUNC
                DW      ACS_FUNC
                DW      ATN_FUNC
                DW      LN
                DW      EXP
                DW      INT
                DW      SQR_FUNC
                DW      SGN
                DW      @ABS
                DW      PEEK
                DW      IN_FUNC
                DW      USR_NO
                DW      STR_DLR
                DW      CHR_DLR
                DW      NOT_FUNC
                DW      DUPLICATE
                DW      N_MOD_M
                DW      JUMP
                DW      STK_DATA
                DW      DEC_JR_NZ
                DW      LESS_0
                DW      GREATER_0
                DW      END_CALC
                DW      GET_ARGT
                DW      TRUNCATE
                DW      FP_CALC_2
                DW      E_TO_FP
                DW      RE_STACK
                DW      SERIES_XX
                DW      STK_CONST_XX
                DW      ST_MEM_XX
                DW      GET_MEM_XX

; The Calculator
CALCULATE:      CALL    STK_PNTRS
GEN_ENT_1:      LD      A,B
                LD      (#5C67),A
GEN_ENT_2:      EXX
                EX      (SP),HL
                EXX
RE_ENTRY:       LD      (#5C65),DE
                EXX
                LD      A,(HL)
                INC     HL
SCAN_ENT:       PUSH    HL
                AND     A
                JP      P,FIRST_3D
                LD      D,A
                AND     #60
                RRCA
                RRCA
                RRCA
                RRCA
                ADD     A,#7C
                LD      L,A
                LD      A,D
                AND     #1F
                JR      ENT_TABLE

FIRST_3D:       CP      #18
                JR      NC,DOUBLE_A
                EXX
                LD      BC,#FFFB
                LD      D,H
                LD      E,L
                ADD     HL,BC
                EXX
DOUBLE_A:       RLCA
                LD      L,A
ENT_TABLE:      LD      DE,TBL_ADDRS
                LD      H,#00
                ADD     HL,DE
                LD      E,(HL)
                INC     HL
                LD      D,(HL)
                LD      HL,RE_ENTRY
                EX      (SP),HL
                PUSH    DE
                EXX
                LD      BC,(#5C66)

; Handle DELETE        
DELETE:         RET

; Single operation
FP_CALC_2:      POP     AF
                LD      A,(#5C67)
                EXX
                JR      SCAN_ENT

; Test that there is enough space between the calc stack and the machine stack
TEST_5_SP:      PUSH    DE
                PUSH    HL
                LD      BC,#0005
                CALL    TEST_ROOM
                POP     HL
                POP     DE
                RET

; Stack floating point number, numeric variable value or an entry in the BEEP's semi-tone table
STACK_NUM:      LD      DE,(#5C65)
                CALL    MOVE_FP
                LD      (#5C65),DE
                RET

; Move a floating point number
DUPLICATE:
MOVE_FP:        CALL    TEST_5_SP
                LDIR
                RET

; Stack literals
STK_DATA:       LD      H,D
                LD      L,E
STK_CONST:      CALL    TEST_5_SP
                EXX
                PUSH    HL
                EXX
                EX      (SP),HL
                PUSH    BC
                LD      A,(HL)
                AND     #C0
                RLCA
                RLCA
                LD      C,A
                INC     C
                LD      A,(HL)
                AND     #3F
                JR      NZ,FORM_EXP
                INC     HL
                LD      A,(HL)
FORM_EXP:       ADD     A,#50
                LD      (DE),A
                LD      A,#05
                SUB     C
                INC     HL
                INC     DE
                LD      B,#00
                LDIR
                POP     BC
                EX      (SP),HL
                EXX
                POP     HL
                EXX
                LD      B,A
                XOR     A
STK_ZEROS:      DEC     B
                RET     Z
                LD      (DE),A
                INC     DE
                JR      STK_ZEROS

; Skip constants
SKIP_CONS:      AND     A
SKIP_NEXT:      RET     Z
                PUSH    AF
                PUSH    DE
                CALL    NO_RW_AT0               ; BSROM - fix for rewriting first bytes of ROM
                CALL    STK_CONST
                POP     DE
                POP     AF
                DEC     A
                JR      SKIP_NEXT

; Calculate memory location
LOC_MEM:        LD      C,A
                RLCA
                RLCA
                ADD     A,C
                LD      C,A
                LD      B,#00
                ADD     HL,BC
                RET

; Get from memory area
GET_MEM_XX:     PUSH    DE
                LD      HL,(#5C68)
                CALL    LOC_MEM
                CALL    MOVE_FP
                POP     HL
                RET

; Stack a constant
STK_CONST_XX:   LD      H,D
                LD      L,E
                EXX
                PUSH    HL
                LD      HL,STK_ZERO
                EXX
                CALL    SKIP_CONS
                CALL    STK_CONST
                EXX
                POP     HL
                EXX
                RET

; Store in a memory area
ST_MEM_XX:      PUSH    HL
                EX      DE,HL
                LD      HL,(#5C68)
                CALL    LOC_MEM
                EX      DE,HL
                CALL    MOVE_FP
                EX      DE,HL
                POP     HL
                RET

; Swap first number with second number
EXCHANGE:       LD      B,#05
SWAP_BYTE:      LD      A,(DE)
                LD      C,(HL)
                EX      DE,HL
                LD      (DE),A
                LD      (HL),C
                INC     HL
                INC     DE
                DJNZ    SWAP_BYTE
                EX      DE,HL
                RET

; Series generator
SERIES_XX:      LD      B,A
                CALL    GEN_ENT_1
                DB      #31                     ;DUPLICATE
                DB      #0F                     ;ADDITION
                DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #A0                     ;STK_ZERO
                DB      #C2                     ;ST_MEM_2
G_LOOP:         DB      #31                     ;DUPLICATE
                DB      #E0                     ;GET_MEM_0
                DB      #04                     ;MULTIPLY
                DB      #E2                     ;GET_MEM_2
                DB      #C1                     ;ST_MEM_1
                DB      #03                     ;SUBTRACT
                DB      #38                     ;END_CALC
                CALL    STK_DATA
                CALL    GEN_ENT_2
                DB      #0F                     ;ADDITION
                DB      #01                     ;EXCHANGE
                DB      #C2                     ;ST_MEM_2
                DB      #02                     ;DELETE
                DB      #35                     ;DEC_JR_NZ
                DB      #EE                     ;back to G_LOOP
                DB      #E1                     ;GET_MEM_1
                DB      #03                     ;SUBTRACT
                DB      #38                     ;END_CALC
                RET

; Find the absolute value of the last value, integer or floating point on the calc stack
ABS:            LD      B,#FF
                JR      NEG_TEST

; Handle unary minus
NEGATE:         CALL    TEST_ZERO
                RET     C
                LD      B,#00
NEG_TEST:       LD      A,(HL)
                AND     A
                JR      Z,INT_CASE
                INC     HL
                LD      A,B
                AND     #80
                OR      (HL)
                RLA
                CCF
                RRA
                LD      (HL),A
                DEC     HL
                RET

INT_CASE:       PUSH    DE
                PUSH    HL
                CALL    INT_FETCH
                POP     HL
                LD      A,B
                OR      C
                CPL
                LD      C,A
                CALL    INT_STORE
                POP     DE
                RET

; Signum
SGN:            CALL    TEST_ZERO
                RET     C
                PUSH    DE
                LD      DE,#0001
                INC     HL
                RL      (HL)
                DEC     HL
                SBC     A,A
                LD      C,A
                CALL    INT_STORE
                POP     DE
                RET

; Handle IN function
IN_FUNC:        CALL    FIND_INT2
                IN      A,(C)
                JR      IN_PK_STK

; Handle PEEK function
PEEK:           CALL    FIND_INT2
                LD      A,(BC)
IN_PK_STK:      JP      STACK_A

; Handle USR number
USR_NO:         CALL    FIND_INT2
                LD      HL,STACK_BC
                PUSH    HL
                PUSH    BC
                RET

; Handle USR string
USR_STR:        CALL    STK_FETCH
                DEC     BC
                LD      A,B
                OR      C
                JR      NZ,REPORT_A
                LD      A,(DE)
                CALL    ALPHA
                JR      C,USR_RANGE
                SUB     #90
                JR      C,REPORT_A
                CP      #15
                JR      NC,REPORT_A
                INC     A
USR_RANGE:      DEC     A
                ADD     A,A
                ADD     A,A
                ADD     A,A
                CP      #A8
                JR      NC,REPORT_A
                LD      BC,(#5C7B)
                ADD     A,C
                LD      C,A
                JR      NC,USR_STACK
                INC     B
USR_STACK:      JP      STACK_BC

REPORT_A:       RST     #08                     ; Error report
                DB      #09                     ; Invalid argument

; Test if top value on calc stack is zero
TEST_ZERO:      PUSH    HL
                PUSH    BC
                LD      B,A
                LD      A,(HL)
                INC     HL
                OR      (HL)
                INC     HL
                OR      (HL)
                INC     HL
                OR      (HL)
                LD      A,B
                POP     BC
                POP     HL
                RET     NZ
                SCF
                RET

; Test if the last value on calc stack is greater than zero
GREATER_0:      CALL    TEST_ZERO
                RET     C
                LD      A,#FF
                JR      SIGN_TO_C

; Handle NOT operator
NOT_FUNC:       CALL    TEST_ZERO
                JR      FP_0_1

; Test if the last value on calc stack is less than zero
LESS_0:         XOR     A
SIGN_TO_C:      INC     HL
                XOR     (HL)
                DEC     HL
                RLCA

; Place an iteger value zero or one at the calc stack or memory area
FP_0_1:         PUSH    HL
                LD      A,#00
                LD      (HL),A
                INC     HL
                LD      (HL),A
                INC     HL
                RLA
                LD      (HL),A
                RRA
                INC     HL
                LD      (HL),A
                INC     HL
                LD      (HL),A
                POP     HL
                RET

; Handle OR operator
OR_FUNC:        EX      DE,HL
                CALL    TEST_ZERO
                EX      DE,HL
                RET     C
                SCF
                JR      FP_0_1

; Handle number AND number
NO_AND_NO:      EX      DE,HL
                CALL    TEST_ZERO
                EX      DE,HL
                RET     NC
                AND     A
                JR      FP_0_1

; Handle string AND number
STR_AND_NO:     EX      DE,HL
                CALL    TEST_ZERO
                EX      DE,HL
                RET     NC
                PUSH    DE
                DEC     DE
                XOR     A
                LD      (DE),A
                DEC     DE
                LD      (DE),A
                POP     DE
                RET

; Perform numeric or string comparison
NO_L_EQL:
NO_GR_EQL:
NOS_NEQL:
NO_GRTR:
NO_LESS:
NOS_EQL:
STR_L_EQL:
STR_GR_EQL:
STRS_NEQL:
STR_GRTR:
STR_LESS:
STRS_EQL:       LD      A,B
                SUB     #08
                BIT     2,A
                JR      NZ,EX_OR_NOT
                DEC     A
EX_OR_NOT:      RRCA
                JR      NC,NU_OR_STR
                PUSH    AF
                PUSH    HL
                CALL    EXCHANGE
                POP     DE
                EX      DE,HL
                POP     AF
NU_OR_STR:      BIT     2,A
                JR      NZ,STRINGS
                RRCA
                PUSH    AF
                CALL    SUBTRACT
                JR      END_TESTS

STRINGS:        RRCA
                PUSH    AF
                CALL    STK_FETCH
                PUSH    DE
                PUSH    BC
                CALL    STK_FETCH
                POP     HL
BYTE_COMP:      LD      A,H
                OR      L
                EX      (SP),HL
                LD      A,B
                JR      NZ,SEC_PLUS
                OR      C
SECND_LOW:      POP     BC
                JR      Z,BOTH_NULL
                POP     AF
                CCF
                JR      STR_TEST

BOTH_NULL:      POP     AF
                JR      STR_TEST

SEC_PLUS:       OR      C
                JR      Z,FRST_LESS
                LD      A,(DE)
                SUB     (HL)
                JR      C,FRST_LESS
                JR      NZ,SECND_LOW
                DEC     BC
                INC     DE
                INC     HL
                EX      (SP),HL
                DEC     HL
                JR      BYTE_COMP

FRST_LESS:      POP     BC
                POP     AF
                AND     A
STR_TEST:       PUSH    AF
                RST     #28                     ;FP_CALC
                DB      #A0                     ;STK_ZERO
                DB      #38                     ;END_CALC

END_TESTS:      POP     AF
                PUSH    AF
                CALL    C,NOT_FUNC
                POP     AF
                PUSH    AF
                CALL    NC,GREATER_0
                POP     AF
                RRCA
                CALL    NC,NOT_FUNC
                RET

; Combine two strings into one
STRS_ADD:       CALL    STK_FETCH
                PUSH    DE
                PUSH    BC
                CALL    STK_FETCH
                POP     HL
                PUSH    HL
                PUSH    DE
                PUSH    BC
                ADD     HL,BC
                LD      B,H
                LD      C,L
                RST     #30
                CALL    STK_STO_D
                POP     BC
                POP     HL
                LD      A,B
                OR      C
                JR      Z,OTHER_STR
                LDIR
OTHER_STR:      POP     BC
                POP     HL
                LD      A,B
                OR      C
                JR      Z,STK_PNTRS
                LDIR

; Check stack pointers
STK_PNTRS:      LD      HL,(#5C65)
                LD      DE,#FFFB
                PUSH    HL
                ADD     HL,DE
                POP     DE
                RET

; Handle CHR$
CHR_DLR:        CALL    NEW_CHR                 ;BSROM - bugfixed CHR$
                JR      C,REPORT_BD
                JR      NZ,REPORT_BD
                PUSH    AF
                LD      BC,#0001
                RST     #30
                POP     AF
                LD      (DE),A
CHR_DLR1:       CALL    STK_STO_D
                EX      DE,HL
                RET

REPORT_BD:      RST     #08                     ; Error report
                DB      #0A                     ; Integer out of range

; Handle VAL and VAL$
VAL:
VAL_DLR:        CALL    VAL2                    ; BSROM - enhanced VAL & VAL$
                PUSH    HL
                LD      A,B
                ADD     A,#E3
                SBC     A,A
                PUSH    AF
                CALL    STK_FETCH
                PUSH    DE
                INC     BC
                RST     #30
                POP     HL
                LD      (#5C5D),DE
                PUSH    DE
                LDIR
                EX      DE,HL
                DEC     HL
                LD      (HL),#0D
                RES     7,(IY+#01)
                CALL    SCANNING
                RST     #18
                CP      #0D
                JR      NZ,V_RPORT_C
                POP     HL
                POP     AF
                XOR     (IY+#01)
                AND     #40
V_RPORT_C:      JP      NZ,REPORT_C
                LD      (#5C5D),HL
                SET     7,(IY+#01)
                CALL    SCANNING
                POP     HL
                LD      (#5C5D),HL
                JR      STK_PNTRS

; Handle STR$
STR_DLR:        LD      BC,#0001
                RST     #30
                LD      (#5C5B),HL
                PUSH    HL
                LD      HL,(#5C51)
                PUSH    HL
                LD      A,#FF
                CALL    CHAN_OPEN
                CALL    PRINT_FP
                POP     HL
                CALL    CHAN_FLAG
                POP     DE
                LD      HL,(#5C5B)
                AND     A
                SBC     HL,DE
                LD      B,H
                LD      C,L
                CALL    STK_STO_D
                EX      DE,HL
                RET

; Read in for INKEY$
READ_IN:        CALL    FIND_INT1
                CP      #10
                JP      NC,REPORT_BB
                LD      HL,(#5C51)
                PUSH    HL
                CALL    CHAN_OPEN
                CALL    INPUT_AD
                LD      BC,#0000
                JR      NC,R_I_STORE
                INC     C
                RST     #30
                LD      (DE),A
R_I_STORE:      CALL    STK_STO_D
                POP     HL
                CALL    CHAN_FLAG
                JP      STK_PNTRS

; Handle CODE
CODE:           CALL    STK_FETCH
                LD      A,B
                OR      C
                JR      Z,STK_CODE
                LD      A,(DE)
STK_CODE        JP      STACK_A

; Handle LEN
LEN:            CALL    STK_FETCH
                JP      STACK_BC

; Decrease the counter
DEC_JR_NZ:      EXX
                PUSH    HL
                LD      HL,#5C67
                DEC     (HL)
                POP     HL
                JR      NZ,JUMP_2
                INC     HL
                EXX
                RET

; Relative jump
JUMP:           EXX
JUMP_2:         LD      E,(HL)
                LD      A,E
                RLA
                SBC     A,A
                LD      D,A
                ADD     HL,DE
                EXX
                RET

; Jump on true
JUMP_TRUE:      INC     DE
                INC     DE
                LD      A,(DE)
                DEC     DE
                DEC     DE
                AND     A
                JR      NZ,JUMP
                EXX
                INC     HL
                EXX
                RET

; End of calculation
END_CALC:       POP     AF
                EXX
                EX      (SP),HL
                EXX
                RET

; Modulus
N_MOD_M:        RST     #28                     ;FP_CALC
                DB      #C0                     ;ST_MEM_0
                DB      #02                     ;DELETE
                DB      #31                     ;DUPLICATE
                DB      #E0                     ;GET_MEM_0
                DB      #05                     ;DIVISION
                DB      #27                     ;INT
                DB      #E0                     ;GET_MEM_0
                DB      #01                     ;EXCHANGE
                DB      #C0                     ;ST_MEM_0
                DB      #04                     ;MULTIPLY
                DB      #03                     ;SUBTRACT
                DB      #E0                     ;GET_MEM_0
                DB      #38                     ;END_CALC
                RET

; Handle INT
INT:            RST     #28                     ;FP_CALC
                DB      #31                     ;DUPLICATE
                DB      #36                     ;LESS_0
                DB      #00                     ;JUMP_TRUE
                DB      #04                     ;to X_NEG
                DB      #3A                     ;TRUNCATE
                DB      #38                     ;END_CALC
                RET

X_NEG:          DB      #31                     ;DUPLICATE
                DB      #3A                     ;TRUNCATE
                DB      #C0                     ;ST_MEM_0
                DB      #03                     ;SUBTRACT
                DB      #E0                     ;GET_MEM_0
                DB      #01                     ;EXCHANGE
                DB      #30                     ;NOT
                DB      #00                     ;JUMP_TRUE
                DB      #03                     ;to EXIT
                DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
EXIT:           DB      #38                     ;END_CALC
                RET

; Exponential
EXP:            RST     #28                     ;FP_CALC
                DB      #3D                     ;RE_STACK
                DB      #34                     ;STK_DATA
                DB      #F1                     ;Exponent
                DB      #38                     ;
                DB      #AA                     ;
                DB      #3B                     ;
                DB      #29                     ;
                DB      #04                     ;MULTIPLY
                DB      #31                     ;DUPLICATE
                DB      #27                     ;INT
                DB      #C3                     ;ST_MEM_3
                DB      #03                     ;SUBTRACT
                DB      #31                     ;DUPLICATE
                DB      #0F                     ;ADDITION
                DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
                DB      #88                     ;SERIES_08
                DB      #13                     ;Exponent
                DB      #36                     ;
                DB      #58                     ;Exponent
                DB      #65                     ;
                DB      #66                     ;
                DB      #9D                     ;Exponent
                DB      #78                     ;
                DB      #65                     ;
                DB      #40                     ;
                DB      #A2                     ;Exponent
                DB      #60                     ;
                DB      #32                     ;
                DB      #C9                     ;
                DB      #E7                     ;Exponent
                DB      #21                     ;
                DB      #F7                     ;
                DB      #AF                     ;
                DB      #24                     ;
                DB      #EB                     ;Exponent
                DB      #2F                     ;
                DB      #B0                     ;
                DB      #B0                     ;
                DB      #14                     ;
                DB      #EE                     ;Exponent
                DB      #7E                     ;
                DB      #BB                     ;
                DB      #94                     ;
                DB      #58                     ;
                DB      #F1                     ;Exponent
                DB      #3A                     ;
                DB      #7E                     ;
                DB      #F8                     ;
                DB      #CF                     ;
                DB      #E3                     ;GET_MEM_3
                DB      #38                     ;END-CALC
                CALL    FP_TO_A
                JR      NZ,N_NEGTV
                JR      C,REPORT_6B
                ADD     A,(HL)
                JR      NC,RESULT_OK
REPORT_6B:      RST     #08                     ; Error report
                DB      #05                     ; Number too big

N_NEGTV:        JR      C,RSLT_ZERO
                SUB     (HL)
                JR      NC,RSLT_ZERO
                NEG
RESULT_OK:      LD      (HL),A
                RET

RSLT_ZERO:      RST     #28                     ;FP_CALC
                DB      #02                     ;DELETE
                DB      #A0                     ;STK_ZERO
                DB      #38                     ;END_CALC
                RET

; Natural logarithm
LN:             RST     #28                     ;FP_CALC
                DB      #3D                     ;RE_STACK
                DB      #31                     ;DUPLICATE
                DB      #37                     ;GREATER_0
                DB      #00                     ;JUMP_TRUE
                DB      #04                     ;to VALID
                DB      #38                     ;END_CALC

REPORT_AB:      RST     #08                     ; Error report
                DB      #09                     ; Invalid argument

VALID:          DB      #A0                     ;STK_ZERO
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                LD      A,(HL)
                LD      (HL),#80
                CALL    STACK_A
                RST     #28                     ;FP_CALC
                DB      #34                     ;STK_DATA
                DB      #38                     ;Exponent
                DB      #00                     ;
                DB      #03                     ;SUBTRACT
                DB      #01                     ;EXCHANGE
                DB      #31                     ;DUPLICATE
                DB      #34                     ;STK_DATA
                DB      #F0                     ;Exponent
                DB      #4C                     ;
                DB      #CC                     ;
                DB      #CC                     ;
                DB      #CD                     ;
                DB      #03                     ;SUBTRACT
                DB      #37                     ;GREATER_0
                DB      #00                     ;JUMP_TURE
                DB      #08                     ;to GRE_8
                DB      #01                     ;EXCHANGE
                DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
                DB      #01                     ;EXCHANGE
                DB      #38                     ;END_CALC
                INC     (HL)
                RST     #28                     ;FP_CALC
GRE_8:          DB      #01                     ;EXCHANGE
                DB      #34                     ;STK_DATA
                DB      #F0                     ;Exponent
                DB      #31                     ;
                DB      #72                     ;
                DB      #17                     ;
                DB      #F8                     ;
                DB      #04                     ;MULTIPLY
                DB      #01                     ;EXCHANGE
                DB      #A2                     ;STK_HALF
                DB      #03                     ;SUBTRACT
                DB      #A2                     ;STK_HALF
                DB      #03                     ;SUBTRACT
                DB      #31                     ;DUPLICATE
                DB      #34                     ;STK_DATA
                DB      #32                     ;Exponent
                DB      #20                     ;
                DB      #04                     ;MULTIPLY
                DB      #A2                     ;STK_HALF
                DB      #03                     ;SUBTRACT
                DB      #8C                     ;SERIES_0C
                DB      #11                     ;Exponent
                DB      #AC                     ;
                DB      #14                     ;Exponent
                DB      #09                     ;
                DB      #56                     ;Exponent
                DB      #DA                     ;
                DB      #A5                     ;
                DB      #59                     ;Exponent
                DB      #30                     ;
                DB      #C5                     ;
                DB      #5C                     ;Exponent
                DB      #90                     ;
                DB      #AA                     ;
                DB      #9E                     ;Exponent
                DB      #70                     ;
                DB      #6F                     ;
                DB      #61                     ;
                DB      #A1                     ;Exponent
                DB      #CB                     ;
                DB      #DA                     ;
                DB      #96                     ;
                DB      #A4                     ;Exponent
                DB      #31                     ;
                DB      #9F                     ;
                DB      #B4                     ;
                DB      #E7                     ;Exponent
                DB      #A0                     ;
                DB      #FE                     ;
                DB      #5C                     ;
                DB      #FC                     ;
                DB      #EA                     ;Exponent
                DB      #1B                     ;
                DB      #43                     ;
                DB      #CA                     ;
                DB      #36                     ;
                DB      #ED                     ;Exponent
                DB      #A7                     ;      
                DB      #9C                     ;
                DB      #7E                     ;
                DB      #5E                     ;
                DB      #F0                     ;Exponent
                DB      #6E                     ;
                DB      #23                     ;
                DB      #80                     ;
                DB      #93                     ;
                DB      #04                     ;MULTIPLY
                DB      #0F                     ;ADDITION
                DB      #38                     ;END_CALC
                RET

; Reduce argument
GET_ARGT:       RST     #28                     ;FP_CALC
                DB      #3D                     ;RE_STACK
                DB      #34                     ;STK_DATA
                DB      #EE                     ;Exponent
                DB      #22                     ;
                DB      #F9                     ;
                DB      #83                     ;
                DB      #6E                     ;
                DB      #04                     ;MULTIPLY
                DB      #31                     ;DUPLICATE
                DB      #A2                     ;STK_HALF
                DB      #0F                     ;ADDITION
                DB      #27                     ;INT
                DB      #03                     ;SUBTRACT
                DB      #31                     ;DUPLICATE
                DB      #0F                     ;ADDITION
                DB      #31                     ;DUPLICATE
                DB      #0F                     ;ADDITION
                DB      #31                     ;DUPLICATE
                DB      #2A                     ;ABS
                DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
                DB      #31                     ;DUPLICATE
                DB      #37                     ;GREATER_0
                DB      #C0                     ;ST-MEM-0
                DB      #00                     ;JUMP_TRUE
                DB      #04                     ;to ZPLUS
                DB      #02                     ;DELETE
                DB      #38                     ;END_CALC
                RET

ZPLUS:          DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
                DB      #01                     ;EXCHANGE
                DB      #36                     ;LESS_0
                DB      #00                     ;JUMP_TRUE
                DB      #02                     ;to YNEG
                DB      #1B                     ;NEGATE
YNEG:           DB      #38                     ;END_CALC
                RET

; Handle cosine
COS_FUNC:       RST     #28                     ;FP_CALC
                DB      #39                     ;GET_ARGT
                DB      #2A                     ;ABS
                DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
                DB      #E0                     ;GET-MEM-0
                DB      #00                     ;JUMP_TRUE
                DB      #06                     ;fwd to C_ENT
                DB      #1B                     ;NEGATE
                DB      #33                     ;jump
                DB      #03                     ;fwd to C_ENT

; Handle sine
SIN_FUNC:       RST     #28                     ;FP_CALC
                DB      #39                     ;GET_ARGT
C_ENT:          DB      #31                     ;DUPLICATE
                DB      #31                     ;DUPLICATE
                DB      #04                     ;MULTIPLY
                DB      #31                     ;DUPLICATE
                DB      #0F                     ;ADDITION
                DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
                DB      #86                     ;SERIES-06
                DB      #14                     ;Exponent                      
                DB      #E6                     ;
                DB      #5C                     ;Exponent
                DB      #1F                     ;
                DB      #0B                     ;
                DB      #A3                     ;Exponent
                DB      #8F                     ;
                DB      #38                     ;
                DB      #EE                     ;
                DB      #E9                     ;Exponent
                DB      #15                     ;
                DB      #63                     ;
                DB      #BB                     ;
                DB      #23                     ;
                DB      #EE                     ;Exponent
                DB      #92                     ;
                DB      #0D                     ;
                DB      #CD                     ;
                DB      #ED                     ;
                DB      #F1                     ;Exponent
                DB      #23                     ;
                DB      #5D                     ;
                DB      #1B                     ;
                DB      #EA                     ;
                DB      #04                     ;MULTIPLY
                DB      #38                     ;END_CALC
                RET

; Handle tangent
TAN_FUNC:       RST     #28                     ;FP_CALC
                DB      #31                     ;DUPLICATE
                DB      #1F                     ;SIN
                DB      #01                     ;EXCHANGE
                DB      #20                     ;COS
                DB      #05                     ;DIVISION
                DB      #38                     ;END_CALC
                RET

; Handle arctan
ATN_FUNC:       CALL    RE_STACK
                LD      A,(HL)
                CP      #81
                JR      C,SMALL
                RST     #28                     ;FP_CALC
                DB      #A1                     ;STK_ONE
                DB      #1B                     ;NEGATE
                DB      #01                     ;EXCHANGE
                DB      #05                     ;DIVISION
                DB      #31                     ;DUPLICATE
                DB      #36                     ;LESS_0
                DB      #A3                     ;STK_PI_2
                DB      #01                     ;EXCHANGE
                DB      #00                     ;JUMP_TRUE
                DB      #06                     ;to CASES
                DB      #1B                     ;NEGATE
                DB      #33                     ;jump
                DB      #03                     ;to CASES
SMALL:          RST     #28                     ;FP_CALC
                DB      #A0                     ;STK_ZERO
CASES:          DB      #01                     ;EXCHANGE
                DB      #31                     ;DUPLICATE
                DB      #31                     ;DUPLICATE
                DB      #04                     ;MULTIPLY
                DB      #31                     ;DUPLICATE
                DB      #0F                     ;ADDITION
                DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
                DB      #8C                     ;SERIES_0C
                DB      #10                     ;Exponent
                DB      #B2                     ;
                DB      #13                     ;Exponent
                DB      #0E                     ;
                DB      #55                     ;Exponent
                DB      #E4                     ;
                DB      #8D                     ;
                DB      #58                     ;Exponent
                DB      #39                     ;
                DB      #BC                     ;
                DB      #5B                     ;Exponent
                DB      #98                     ;
                DB      #FD                     ;
                DB      #9E                     ;Exponent
                DB      #00                     ;
                DB      #36                     ;
                DB      #75                     ;
                DB      #A0                     ;Exponent
                DB      #DB                     ;
                DB      #E8                     ;
                DB      #B4                     ;
                DB      #63                     ;Exponent
                DB      #42                     ;
                DB      #C4                     ;
                DB      #E6                     ;Exponent
                DB      #B5                     ;
                DB      #09                     ;
                DB      #36                     ;
                DB      #BE                     ;
                DB      #E9                     ;Exponent
                DB      #36                     ;
                DB      #73                     ;
                DB      #1B                     ;
                DB      #5D                     ;
                DB      #EC                     ;Exponent
                DB      #D8                     ;
                DB      #DE                     ;
                DB      #63                     ;
                DB      #BE                     ;
                DB      #F0                     ;Exponent
                DB      #61                     ;
                DB      #A1                     ;
                DB      #B3                     ;
                DB      #0C                     ;
                DB      #04                     ;MULTIPLY
                DB      #0F                     ;ADDITION
                DB      #38                     ;END_CALC
                RET

; Handle arcsin
ASN_FUNC:       RST     #28                     ;FP_CALC
                DB      #31                     ;DUPLICATE
                DB      #31                     ;DUPLICATE
                DB      #04                     ;MULTIPLY
                DB      #A1                     ;STK_ONE
                DB      #03                     ;SUBTRACT
                DB      #1B                     ;NEGATE
                DB      #28                     ;SQR
                DB      #A1                     ;STK_ONE
                DB      #0F                     ;ADDITION
                DB      #05                     ;DIVISION
                DB      #24                     ;ATN
                DB      #31                     ;DUPLICATE
                DB      #0F                     ;ADDITION
                DB      #38                     ;END_CALC
                RET

; Handle arccos
ACS_FUNC:       RST     #28                     ;FP_CALC
                DB      #22                     ;ASN
                DB      #A3                     ;STK_PI_2
                DB      #03                     ;SUBTRACT
                DB      #1B                     ;NEGATE
                DB      #38                     ;END_CALC
                RET

; Handle square root
SQR_FUNC:       RST     #28                     ;FP_CALC
                DB      #31                     ;DUPLICATE
                DB      #30                     ;NOT
                DB      #00                     ;JUMP_TRUE
                DB      #1E                     ;to LAST
                DB      #A2                     ;STK_HALF
                DB      #38                     ;END_CALC

; Handle exponential
TO_POWER:       RST     #28                     ;FP_CALC
                DB      #01                     ;EXCHANGE
                DB      #31                     ;DUPLICATE
                DB      #30                     ;NOT
                DB      #00                     ;JUMP_TRUE
                DB      #07                     ;to XISO
                DB      #25                     ;LN
                DB      #04                     ;MULTIPLY
                DB      #38                     ;END_CALC
                JP      EXP                    

XISO:           DB      #02                     ;DELETE
                DB      #31                     ;DUPLICATE
                DB      #30                     ;NOT
                DB      #00                     ;JUMP_TRUE
                DB      #09                     ;to ONE
                DB      #A0                     ;STK_ZERO
                DB      #01                     ;EXCHANGE
                DB      #37                     ;GREATER_0
                DB      #00                     ;JUMP_TRUE
                DB      #06                     ;to LAST
                DB      #A1                     ;STK_ONE
                DB      #01                     ;EXCHANGE
                DB      #05                     ;DIVISION
ONE:            DB      #02                     ;DELETE
                DB      #A1                     ;STK_ONE
LAST:           DB      #38                     ;END_CALC
                RET

; BSROM additional routines
; Input of HEX numbers
HEXA:           LD      HL,SCAN_FUNC
                CP      #25
                RET     NZ
                POP     AF
                CALL    SYNTAX_Z
                JP      NZ,S_STK_DEC
                LD      DE,#0000
HEX1:           RST     #20
                CALL    ALPHANUM
                JR      NC,HEXEND
                CP      #41
                JR      C,CIS
                OR      #20
                CP      #67
                JR      NC,HEXEND
                SUB     #27
CIS:            AND     #0F
                LD      C,A
                LD      A,D
                AND     #F0
                JP      NZ,REPORT_6
                LD      A,C
                EX      DE,HL
                ADD     HL,HL
                ADD     HL,HL
                ADD     HL,HL
                ADD     HL,HL
                OR      L
                LD      L,A
                EX      DE,HL
                JR      HEX1

HEXEND:         CALL    BIN_END
                JP      S_BIN_1

; Allow number in VAL$ and VAL
VAL1:           CP      #18
                RET     Z
                CP      #9D
                RET     Z
                XOR     (IY+#01)
                RET

; Evaluation of VAL and VAL$
VAL2:           LD      HL,(#5C5D)
                BIT     6,(IY+#01)
                RET     Z
                POP     AF
                PUSH    BC
                CALL    FIND_INT2
                POP     AF
                RRCA
                JR      NC,DOLAR
                LD      H,B
                LD      L,C
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                JP      STACK_BC

DOLAR:          PUSH    BC
                LD      BC,#0004
                RST     #30
                POP     HL
                PUSH    DE
                LD      A,H
                CALL    HEX99
                LD      A,L
                CALL    HEX99
                POP     DE
                JP      CHR_DLR1

; Hex numbers
HEX99:          PUSH    AF
                RRCA
                RRCA
                RRCA
                RRCA
                CALL    HEX98
                POP     AF
HEX98:          AND     #0F
                OR      #30
                CP      #3A
                JR      C,HEX98_1
                ADD     A,#27
HEX98_1:        LD      (DE),A
                INC     DE
                RET

INFSUB:         LD      DE,COPYRIGHT+5
                CALL    PO_TOKENS1
                JP      HLO

MM:             DW      #FFFF

USERJP:         JP      #0052

DISKTOOLS:      DW      #0052

; 128k reset
RES128:         DI
                XOR     A
                LD      I,A
                OUT     (#FE),A
                LD      E,#17
CC0:            LD      BC,#7FFD
                OUT     (C),E
                LD      BC,#0008
                LD      H,A
                LD      L,A
                LD      SP,HL
CC1:            PUSH    HL
                PUSH    HL
                PUSH    HL
                PUSH    HL
                DJNZ    CC1
                DEC     C
                JR      NZ,CC1
                DEC     E
                BIT     4,E
                JR      NZ,CC0
                LD      B,#5C
CC2:            LD      (BC),A
                INC     C
                JR      NZ,CC2
                DEC     HL
                JP      RAM_DONE2

; NMI Menu
NMI_MENU:       PUSH    AF
                PUSH    HL
                LD      HL,#BFE0
                ADD     HL,SP
                JR      C,MM1
                LD      SP,#5800
                LD      HL,NMI_MENU
                PUSH    HL
                PUSH    HL
                PUSH    HL
MM1:            PUSH    BC
                PUSH    DE
                PUSH    IX
                LD      A,I
                PUSH    AF
MMRET:          DI
                LD      C,#FE
                LD      A,R
                OUT     (C),A
                OUT     (C),0
                CALL    KEY_SCAN
                INC     E
                JR      Z,MMRET
                DEC     E
                CALL    K_TEST
                LD      XH,A
                LD      A,#22
                OUT     (#FE),A
PUST:           CALL    KEY_SCAN
                INC     E
                JR      NZ,PUST
                LD      A,#08
                OUT     (#FE),A
                LD      A,XH
                LD      HL,MMRET
                PUSH    HL
                CP      'U'                     ; U - user function.
                JR      Z,USERJP
                CP      'E'                     ; E - extended 128k reset.
                JR      Z,RES128
                CP      'I'                     ; I - quiet AY. Reset FDC, DMA and stop disk drive if MB-02 is present.
                JP      Z,HARD
                CP      'T'                     ; T - set tape as actual device (only on MB-02).
                JP      Z,JP15522
                CP      'D'                     ; D - set disk as actual device (only on MB-02)
                JP      Z,JP15524
                CP      'B'                     ; B - warm start. BASIC program with variables is not deleted.
                JP      Z,BASIC
                CP      'Z'                     ; Z - user function like 'U' but this key is reserved for MB-02 applications.
                LD      HL,(DISKTOOLS)
                JR      NZ,DSKIP
                JP      (HL)
DSKIP:          CP      'N'                     ; N - CLEAR #5FFF: NEW - memory above #6000 is not changed.
                LD      DE,#5FFF
                JR      Z,RESNEW
                CP      'R'                     ; R - CLEAR #FFFF: NEW - classic 48k reset.
                LD      D,E
RESNEW:         JP      Z,NEW_1
NERES:          CP      'S'                     ; S - save SCREEN$ on tape, or disk if MB-02 is present.
                JR      NZ,NESAV
                LD      IX,#4000
                LD      DE,#1B00
                LD      A,#FF
                JP      SA_BYTES1
NESAV:          CP      'Q'                     ; Q - quit / return from NMI menu.
                JR      Z,QUIT
                CP      'M'                     ; M - jump to MRS debugger (MRS must be loaded in memory).
                JR      Z,MRS
                CALL    NUMERIC
                RET     C
                LD      HL,#4000
                ADD     HL,SP
                JR      NC,DD0
                LD      SP,#57F0
DD0:            POP     BC
                CALL    OUT128
                JP      MMRET

; Quit from NMI Menu           
QUIT:           POP     AF
                POP     AF
                LD      I,A
                JP      PO,RET_I
                EI
RET_I:          POP     IX
                POP     DE
                POP     BC
                POP     HL
                POP     AF
                RET

; Jump to MRS debugger
MRS:            POP     AF
                POP     AF
                LD      I,A
                POP     IX
                POP     DE
                POP     BC
                POP     HL
                POP     AF
                LD      (#F4FF),HL
                POP     HL
                LD      (#F544),HL
                JP      #F514

; Print general number
HLODVA:         LD      A,':'
                RST     #10
HLO:            LD      B,H
                LD      C,L
                CALL    STACK_BC
                JP      PRINT_FP

TT:             DW      #0000                   ;DS #39FF-TT
UU:             DW      #FFFF

DISPL:          LD      C,A
                LD      A,(IY+#02)
                CP      #10
                LD      A,C
                JR      NZ,DIS
                LD      BC,#FBFE
                IN      C,(C)
                RRC     C
                JR      C,DII
PUSTI:          XOR     A
                IN      A,(#FE)
                RRCA
                JR      NC,PUSTI
                LD      SP,(#5C3F)              ;LISTSP
                RES     5,(IY+#01)
                RET

DII:            LD      C,(IY+#76)
                BIT     1,C                     ;bit1=1 don't show colors during autolist
                JR      Z,DIS
                CP      #0D
                JR      Z,DIS
                CP      #20
                JR      C,DIP
DIS:            JP      PO_FETCH

DIP:            BIT     2,C                     ;bit2=1 show comma instead of codes
                JR      NZ,DID
                POP     AF
DID:            LD      A,#1E
                JR      DIS

; General number printing with spaces
NUM_NEW:        PUSH    DE
                PUSH    HL
                LD      E,' '
                DB      #06
NUMCOM:         LD      L,C
                LD      BC,#D8F0
                CALL    OUT_SP_NO
                JP      OUT_NUM_3

; Check of BASIC program presence
LIN2:           CALL    LINE_NO
                PUSH    HL
                LD      HL,(#5C53)
                LD      A,(HL)
                POP     HL
                RET

; Test of numbers at the begin of line
LIN3:           RST     #18
                CALL    NUMERIC
                PUSH    AF
                CALL    E_LINE_NO
                POP     AF
                RET

; Show empty cursor instead of '*'
LIN4:           LD      A,(IY+#02)
                CP      #10
                JR      Z,LL40
                LD      D,#20
LL40:           PUSH    HL
                XOR     A
                LD      HL,(#5C51)              ;channel R?
                LD      BC,#5CC0
                SBC     HL,BC
                POP     HL
                JR      Z,LL41
                BIT     0,(IY+#76)
                JP      Z,OUT_NUM_2
                DB      #01
LL41:           LD      D,#00                   ; no cursor at 'R'
                PUSH    DE
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                EX      DE,HL
                CALL    NUM_NEW
                EX      DE,HL
                POP     DE
                RET

; Moving around edit zone
DOLE:           CALL    ED_RIGHT
                LD      IX,ED_RIGHT
                JR      NZ,HORDOL
                LD      HL,#5C49
                RET

HORE:           CALL    ED_LEFT
                LD      IX,ED_LEFT
                JR      NC,HORDOL
                LD      HL,(#5C49)
                RET

HORDOL:         POP     BC
                LD      B,#00
HD1:            INC     B
                BIT     5,B
                RET     NZ
                PUSH    BC
                CALL    L_03F0
                POP     BC
                LD      A,(HL)
                CP      #0D
                RET     Z
                CP      ' '
                JR      C,HD1+1
                SUB     #A5
                JR      C,HD1
                EXX
                LD      HL,INCB-2
                LD      (#5C51),HL
                CALL    PO_TOKENS
                CALL    ED_LIST_1
                EXX
                JR      HD1+1

                DW      INCB
INCB:           EXX
                INC     B
                EXX
                RET

; Switch 128k bank
BANKA:          RST     #20
                CALL    FETCH_NUM
                CALL    CHECK_END
                CALL    FIND_INT1
OUT128:         AND     #0F
                OR      #10
                LD      BC,#7FFD
                OUT     (C),A
                RET

; Comma instead of semicolon
EDIT:           RST     #20
                CALL    FETCH_NUM
                CALL    CHECK_END
                CALL    FIND_INT2
                LD      (#5C49),BC
                CALL    SET_MIN
                CALL    CLS_LOWER
                RES     5,(IY+#37)
VV:             DW      #FFFF
                RES     3,(IY+#01)
                CALL    ED_EDIT
                LD      SP,(#5C3D)
                POP     AF
                JP      MAIN_2

; Modified CLS command
NEW_CLS:        CALL    FIND_INT1
                OR      A
                JR      Z,NECOL
                LD      (#5C48),A
                LD      (#5C8D),A
                CALL    SA_LD_RET
NECOL:          JP      CLS

; New commands
COMM:           CP      #27                     ;"'"
                JR      Z,BANKA
                CP      #2C                     ;","
                JR      Z,EDIT
                LD      HL,NEWTAB
COM1:           BIT     7,(HL)
                JP      NZ,PRINT
                CP      (HL)
                INC     HL
                LD      E,(HL)
                INC     HL
                LD      D,(HL)
                INC     HL
                JR      NZ,COM1
                RST     #20
                CALL    CHECK_END
                EX      DE,HL
                JP      (HL)

NEWTAB:         DB      '#'
                DW      54885  
                DB      '_'
                DW      #66
                DB      '*'
                DW      HEA
                DB      '?'
                DW      INFO
                DB      #7F                     ;(c)
                DW      BASIC
                DB      '^'
                DW      RES128
                DB      '!'
                DW      HARD
                DB      '='
                DW      USERJP

; Quiet AY. Reset FDC, DMA, stop drives if MB-02 is present
HARD:           XOR     A
                LD      BC,#FFFD
                OUT     (#13),A                 ; FDD motor
                LD      A,#D0
                OUT     (#0F),A                 ; FDC
                LD      A,#C3
                OUT     (#0B),A                 ; DMA
                LD      A,#07  
                OUT     (C),A                   ; AY
                LD      A,#BF
                OUT     (#FD),A
                LD      A,#0D
                OUT     (C),A
                LD      A,#80
                OUT     (#FD),A
                RET

; Warm start
BASIC:          LD      HL,INIT_CHAN
                LD      DE,#5CB6
                LD      BC,#0015
                LD      (#5C4F),DE
                LDIR
                LD      HL,#3C00
                LD      (#5C36),HL
                LD      HL,#0040
                LD      (#5C38),HL
                LD      IY,#5C3A
                LD      HL,(#5CB2)
                LD      (HL),#3E
                DEC     HL
                LD      SP,HL
                DEC     HL
                DEC     HL
                LD      (#5C3D),HL
                IM      1
                EI
                LD      HL,(#5C59)
                JP      WARM_ST

; Enhanced POKE
NEW_POKE:       CALL    SYNTAX_Z
                CALL    NZ,FIND_INT2
                LD      D,B
                LD      E,C
POKLOP:         RST     #18
                CP      #2C
                JR      Z,POKOK
                CP      #3B
                RET     NZ
POKOK:          PUSH    DE
                PUSH    AF
                RST     #20
                CALL    SCANNING
                POP     AF
                POP     DE
                CALL    SYNTAX_Z
                JR      Z,POKLOP
                BIT     6,(IY+#01)
                JR      NZ,POKNUM
POKRET:         PUSH    AF
                PUSH    DE
                CALL    STK_FETCH
                EX      DE,HL
                POP     DE
                LD      A,B
                OR      C
                JR      Z,POKNIC
                LDIR
                POP     AF
                RRCA
                JR      NC,POKLOP
                LD      H,D
                LD      L,E
                DEC     HL
                SET     7,(HL)
                PUSH    AF
POKNIC:         POP     AF
                JR      POKLOP

POKNUM:         PUSH    DE
                RRCA
                JR      C,POKDW
POKDB:          CALL    FIND_INT1
                POP     DE
                JR      POKLD

POKDW:          CALL    FIND_INT2
                POP     DE
                LD      A,C
                LD      (DE),A
                INC     DE
                LD      A,B
POKLD:          LD      (DE),A
                INC     DE
                JR      POKLOP

SS:             DB      #FF
WW:             DW      #FFFF

; New line number test
LIN1:           CALL    CP_LINES
                RET     NC
                LD      A,(HL)
                AND     #C0
                RET     NZ
                SCF
                RET

; New boot screen
INFO:           CALL    CLS
                LD      A,#FE
                CALL    CHAN_OPEN
                LD      HL,(#5C4B)
                LD      BC,(#5C53)
                XOR     A
                PUSH    HL
                SBC     HL,BC
                CALL    INFSUB
                POP     BC
                SCF
                LD      HL,(#5C59)
                SBC     HL,BC
                LD      A,#01
                CALL    INFSUB
                LD      BC,(#5C65)
                LD      HL,#0000
                ADD     HL,SP
                SBC     HL,BC
                LD      A,#02
                CALL    INFSUB
                JP      PRINT_5

; Header command
HEA:            LD      A,#FE
                CALL    CHAN_OPEN
ZNOVU:          DI
                LD      IX,#5C9E
                LD      DE,#0010
                XOR     A
                INC     E
                SCF
                EX      AF,AF'
                LD      A,#0E
                OUT     (#FE),A
                IN      A,(#FE)
                RRA
                CALL    LD_BYTES1
                CALL    SA_LD_RET
                JR      NC,ZNOVU
                LD      (#5C8C),A
                LD      A,#17
                RST     #10
                XOR     A
                RST     #10
                RST     #10
                LD      HL,#5C9E
                LD      A,(HL)
                OR      #30
                RST     #10
                LD      A,#3A
                RST     #10
                LD      B,#0A
MENO:           INC     HL
                LD      A,(HL)
                CP      #20
                JR      NC,MENO1
                LD      A,#1E
MENO1:          RST     #10
                DJNZ    MENO
                LD      A,#17
                RST     #10
                LD      A,#15
                RST     #10
                RST     #10
                LD      HL,(#5CAB)
                CALL    NUM_NEW
                LD      HL,(#5CA9)
                CALL    HLODVA
                LD      A,#0D
                RST     #10
                JR      ZNOVU

; Unused bytes
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DB      #FF

JP15522:        RET

                DB      #FF

JP15524:        RET

                DB      #FF

                DB      " Busy soft rom "
                DB      VER1, VER2, VER3
                DB      " "

; Unused bytes
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DW      #FFFF
                DB      #FF
; BSROM - new characters
CHAR_SET_N:     DB      #00,#00,#00,#00,#00,#00,#7E,#00 ;line
                DB      #00,#7E,#7E,#7E,#7E,#7E,#7E,#00 ;square

; Character set
CHAR_SET:       DB      #00,#00,#00,#00,#00,#00,#00,#00 ;space
                DB      #00,#10,#10,#10,#10,#00,#10,#00 ;!
                DB      #00,#24,#24,#00,#00,#00,#00,#00 ;"
                DB      #00,#24,#7E,#24,#24,#7E,#24,#00 ;#
                DB      #00,#08,#3E,#28,#3E,#0A,#3E,#08 ;$
                DB      #00,#62,#64,#08,#10,#26,#46,#00 ;%
                DB      #00,#10,#28,#10,#2A,#44,#3A,#00 ;&
                DB      #00,#08,#10,#00,#00,#00,#00,#00 ;'

                DB      #00,#04,#08,#08,#08,#08,#04,#00 ;(
                DB      #00,#20,#10,#10,#10,#10,#20,#00 ;)
                DB      #00,#00,#14,#08,#3E,#08,#14,#00 ;*
                DB      #00,#00,#08,#08,#3E,#08,#08,#00 ;+
                DB      #00,#00,#00,#00,#00,#08,#08,#10 ;,
                DB      #00,#00,#00,#00,#3E,#00,#00,#00 ;-
                DB      #00,#00,#00,#00,#00,#18,#18,#00 ;.
                DB      #00,#00,#02,#04,#08,#10,#20,#00 ;/
                DB      #00,#3C,#46,#4A,#52,#62,#3C,#00 ;0
                DB      #00,#18,#28,#08,#08,#08,#3E,#00 ;1
                DB      #00,#3C,#42,#02,#3C,#40,#7E,#00 ;2
                DB      #00,#3C,#42,#0C,#02,#42,#3C,#00 ;3
                DB      #00,#08,#18,#28,#48,#7E,#08,#00 ;4
                DB      #00,#7E,#40,#7C,#02,#42,#3C,#00 ;5
                DB      #00,#3C,#40,#7C,#42,#42,#3C,#00 ;6
                DB      #00,#7E,#02,#04,#08,#10,#10,#00 ;7
                DB      #00,#3C,#42,#3C,#42,#42,#3C,#00 ;8
                DB      #00,#3C,#42,#42,#3E,#02,#3C,#00 ;9
                DB      #00,#00,#00,#10,#00,#00,#10,#00 ;:
                DB      #00,#00,#10,#00,#00,#10,#10,#20 ;;
                DB      #00,#00,#04,#08,#10,#08,#04,#00 ;<
                DB      #00,#00,#00,#3E,#00,#3E,#00,#00 ;=
                DB      #00,#00,#10,#08,#04,#08,#10,#00 ;>
                DB      #00,#3C,#42,#04,#08,#00,#08,#00 ;?
                DB      #00,#3C,#02,#3A,#4A,#4A,#3C,#00 ;@ BSROM - more beautiful @ character
                DB      #00,#3C,#42,#42,#7E,#42,#42,#00 ;A
                DB      #00,#7C,#42,#7C,#42,#42,#7C,#00 ;B
                DB      #00,#3C,#42,#40,#40,#42,#3C,#00 ;C
                DB      #00,#78,#44,#42,#42,#44,#78,#00 ;D
                DB      #00,#7E,#40,#7C,#40,#40,#7E,#00 ;E
                DB      #00,#7E,#40,#7C,#40,#40,#40,#00 ;F
                DB      #00,#3C,#42,#40,#4E,#42,#3C,#00 ;G
                DB      #00,#42,#42,#7E,#42,#42,#42,#00 ;H
                DB      #00,#3E,#08,#08,#08,#08,#3E,#00 ;I
                DB      #00,#02,#02,#02,#42,#42,#3C,#00 ;J
                DB      #00,#44,#48,#70,#48,#44,#42,#00 ;K
                DB      #00,#40,#40,#40,#40,#40,#7E,#00 ;L
                DB      #00,#42,#66,#5A,#42,#42,#42,#00 ;M
                DB      #00,#42,#62,#52,#4A,#46,#42,#00 ;N
                DB      #00,#3C,#42,#42,#42,#42,#3C,#00 ;O
                DB      #00,#7C,#42,#42,#7C,#40,#40,#00 ;P
                DB      #00,#3C,#42,#42,#52,#4A,#3C,#00 ;Q
                DB      #00,#7C,#42,#42,#7C,#44,#42,#00 ;R
                DB      #00,#3C,#40,#3C,#02,#42,#3C,#00 ;S
                DB      #00,#FE,#10,#10,#10,#10,#10,#00 ;T
                DB      #00,#42,#42,#42,#42,#42,#3C,#00 ;U
                DB      #00,#42,#42,#42,#42,#24,#18,#00 ;V
                DB      #00,#42,#42,#42,#42,#5A,#24,#00 ;W
                DB      #00,#42,#24,#18,#18,#24,#42,#00 ;X
                DB      #00,#82,#44,#28,#10,#10,#10,#00 ;Y
                DB      #00,#7E,#04,#08,#10,#20,#7E,#00 ;Z
                DB      #00,#0E,#08,#08,#08,#08,#0E,#00 ;[
                DB      #00,#00,#40,#20,#10,#08,#04,#00 ;\
                DB      #00,#70,#10,#10,#10,#10,#70,#00 ;]
                DB      #00,#10,#38,#54,#10,#10,#10,#00 ;^
                DB      #00,#00,#00,#00,#00,#00,#00,#FF ;_
                DB      #00,#1C,#22,#78,#20,#20,#7E,#00 ;┬г
                DB      #00,#00,#38,#04,#3C,#44,#3C,#00 ;a
                DB      #00,#20,#20,#3C,#22,#22,#3C,#00 ;b
                DB      #00,#00,#1C,#20,#20,#20,#1C,#00 ;c
                DB      #00,#04,#04,#3C,#44,#44,#3C,#00 ;d
                DB      #00,#00,#38,#44,#78,#40,#3C,#00 ;e
                DB      #00,#0C,#10,#18,#10,#10,#10,#00 ;f
                DB      #00,#00,#3C,#44,#44,#3C,#04,#38 ;g
                DB      #00,#40,#40,#78,#44,#44,#44,#00 ;h
                DB      #00,#10,#00,#30,#10,#10,#38,#00 ;i
                DB      #00,#04,#00,#04,#04,#04,#24,#18 ;j
                DB      #00,#20,#28,#30,#30,#28,#24,#00 ;k
                DB      #00,#10,#10,#10,#10,#10,#0C,#00 ;l
                DB      #00,#00,#68,#54,#54,#54,#54,#00 ;m
                DB      #00,#00,#78,#44,#44,#44,#44,#00 ;n
                DB      #00,#00,#38,#44,#44,#44,#38,#00 ;o
                DB      #00,#00,#78,#44,#44,#78,#40,#40 ;p
                DB      #00,#00,#3C,#44,#44,#3C,#04,#06 ;q
                DB      #00,#00,#1C,#20,#20,#20,#20,#00 ;r
                DB      #00,#00,#38,#40,#38,#04,#78,#00 ;s
                DB      #00,#10,#38,#10,#10,#10,#0C,#00 ;t
                DB      #00,#00,#44,#44,#44,#44,#38,#00 ;u
                DB      #00,#00,#44,#44,#28,#28,#10,#00 ;v
                DB      #00,#00,#44,#54,#54,#54,#28,#00 ;w
                DB      #00,#00,#44,#28,#10,#28,#44,#00 ;x
                DB      #00,#00,#44,#44,#44,#3C,#04,#38 ;y
                DB      #00,#00,#7C,#08,#10,#20,#7C,#00 ;z
                DB      #00,#0E,#08,#30,#08,#08,#0E,#00 ;{
                DB      #00,#08,#08,#08,#08,#08,#08,#00 ;|
                DB      #00,#70,#10,#0C,#10,#10,#70,#00 ;}
                DB      #00,#14,#28,#00,#00,#00,#00,#00 ;~
                DB      #3C,#42,#99,#A1,#A1,#99,#42,#3C ;(c)