News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_abalore

Address to RUN a preloaded BASIC file

Started by abalore, 21:18, 11 January 25

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

abalore

Hello,

does anyone know what address to call in order to execute the RUN command in BASIC? The BASIC program is preloaded at address &170 and the context loaded at &A670. Preferable an address that works with all BASIC versions.

ZorrO

#1
If you mean RUN binary program:
adr=&A670:CALL @adr
You can also SAVE"name.bin",b,start,long,auto-start
And later run"name.bin
CPC+PSX 4ever

abalore

Quote from: ZorrO on 23:36, 11 January 25If you mean RUN binary program:
CALL address
You can also SAVE"name.bin",b,start,long,auto-start
And later run"name.bin


No, I mean what's the entry point in the BASIC jump table for the tokenised RUN command. In order to make a call from assembler that runs the current stored BASIC program.

Prodatron

#3
Maybe this helps:

https://github.com/Bread80/Amstrad-CPC-BASIC-Source/blob/main/LoadSaveRun.asm

It's address #EA78 in Basic ROM (6128 version), but I have no idea how to handle the optional line number parameter.

*EDIT* oh, yes, it works :)

10 print"Hello"
20 goto 10

then assemble...

org #4000
rst #10
dw #ea78
ret

then
CALL &4000
Hello
Hello
Hello
Hello
...

you can even ESC+ESC and return to the prompt.

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

abalore

Quote from: Prodatron on 01:34, 12 January 25Maybe this helps:

https://github.com/Bread80/Amstrad-CPC-BASIC-Source/blob/main/LoadSaveRun.asm

It's address #EA78 in Basic ROM (6128 version), but I have no idea how to handle the optional line number parameter.

*EDIT* oh, yes, it works :)

10 print"Hello"
20 goto 10

then assemble...

org #4000
rst #10
dw #ea78
ret

then
CALL &4000
Hello
Hello
Hello
Hello
...

you can even ESC+ESC and return to the prompt.
Great! That's what I was looking for. You saved me precious time debugging myself. Thank you!

Nich

#5
Below is some code that starts from a "clean sheet" by initialising AMSDOS and other ROMs, loading a BASIC program, setting up a character matrix for BASIC to use, and finally, running the BASIC program. It will also detect which model of CPC is being used. :)

I've tested it on a few BASIC listings but I can't guarantee it will work with every BASIC program!

    org &8000

;Initialise all ROMs, including AMSDOS
start:
    call &bb57                  ;Disable firmware text output to the screen

    ld hl,(&be7d)               ;Get address where drive number is stored
    inc hl
    inc hl
    ld a,(hl)                   ;Get drive number (A = 0, B = 1)
    push af                     ;Store drive number

    ld de,&40                   ;DE = first usable byte of RAM
    ld hl,&abff                 ;HL = last usable byte of RAM
    call &bccb                  ;Initialise all background ROMs
    ld (last_byte_addr),hl      ;Store the new last usable byte of RAM, after
                                ;space has been reserved for AMSDOS and other
                                ;ROMs

    pop af                      ;Get drive number
    ld hl,(&be7d)               ;Get address where drive number is stored
    ld (hl),a                   ;Set drive number for use by BASIC

    call &bb54                  ;Re-enable firmware text output to the screen

;Load the BASIC program
load_file:
    ld hl,filename              ;HL = filename address
    ld de,&c000                 ;DE = file buffer address
    ld b,12                     ;B = length of filename
    call &bc77                  ;Open the file; on exit, BC contains file
                                ;length
    ld hl,&170                  ;BASIC program starts at &170
    push hl                     ;Store start address of BASIC program
    add hl,bc                   ;Calculate address of last byte of BASIC
    dec hl                      ;program
    ld (basic_prog_end_addr),hl ;Store it for use later
    pop hl                      ;Get start address of BASIC program
    call &bc83                  ;Read the contents of the file
    call &bc7a                  ;Close the file

;Set up a matrix table for characters 240-255 to be redefined
    ld de,240                   ;DE = first character in matrix table
    ld hl,(last_byte_addr)      ;HL = last usable byte of RAM by BASIC
    ld bc,16*8                  ;16 characters in table, 8 bytes for each
                                ;character
    sbc hl,bc                   ;Calculate value of HIMEM
    push hl                     ;Store it
    inc hl                      ;Start address of matrix table is the byte
                                ;following HIMEM
    call &bbab                  ;Initialise the matrix table

;Check which version of BASIC is being used
    ld c,0                      ;0 = BASIC ROM number
    call &b90f                  ;Select the BASIC ROM
    ld hl,(basic_prog_end_addr) ;Get end address of BASIC program
    pop de                      ;Get value of HIMEM (now in DE)
    ld bc,(last_byte_addr)      ;BC = last usable byte of RAM
    ld a,(&c002)                ;Read the version number
    and a                       ;Is it 0 (i.e. CPC464 BASIC)?
    jr z,start_basic_program_cpc464

;BASIC 1.1 is being used
    ld (&ae66),hl               ;Store the end address of the BASIC program
    ld (&ae68),hl               ;four times
    ld (&ae6a),hl
    ld (&ae6c),hl
    ex de,hl                    ;Now HL = value of HIMEM
    ld (&ae5e),hl               ;Store HIMEM
    ld (&ae60),bc               ;Store last usable byte of RAM

    cp 1                        ;Is a CPC664 being used (version 1)?
    jp z,&ea7d                  ;Yes
    jp &ea78                    ;No, so run the BASIC program

;BASIC 1.0 is being used
start_basic_program_cpc464:
    ld (&ae83),hl               ;Store the end address of the BASIC program
    ld (&ae85),hl               ;four times
    ld (&ae87),hl
    ld (&ae89),hl
    ex de,hl                    ;Now HL = value of HIMEM
    ld (&ae7b),hl               ;Store HIMEM
    ld (&ae7d),bc               ;Store last usable byte of RAM
    jp &e9bd                    ;Run the BASIC program

filename:
    db "PROGRAM .BAS"

basic_prog_end_addr:
    dw 0
last_byte_addr:                 ;Store the address of the last usable byte of
    dw 0                        ;RAM by BASIC

Hmmm... I should probably also upload this to CPCWiki somewhere... ::)

Brocky

Quote from: Nich on 22:04, 14 January 25Below is some code that starts from a "clean sheet" by initialising AMSDOS and other ROMs, loading a BASIC program, setting up a character matrix for BASIC to use, and finally, running the BASIC program. It will also detect which model of CPC is being used. :)

I've tested it on a few BASIC listings but I can't guarantee it will work with every BASIC program!

    org &8000

;Initialise all ROMs, including AMSDOS
start:
    call &bb57                  ;Disable firmware text output to the screen

    ld hl,(&be7d)               ;Get address where drive number is stored
    inc hl
    inc hl
    ld a,(hl)                   ;Get drive number (A = 0, B = 1)
    push af                     ;Store drive number

    ld de,&40                   ;DE = first usable byte of RAM
    ld hl,&abff                 ;HL = last usable byte of RAM
    call &bccb                  ;Initialise all background ROMs
    ld (last_byte_addr),hl      ;Store the new last usable byte of RAM, after
                                ;space has been reserved for AMSDOS and other
                                ;ROMs

    pop af                      ;Get drive number
    ld hl,(&be7d)               ;Get address where drive number is stored
    ld (hl),a                   ;Set drive number for use by BASIC

    call &bb54                  ;Re-enable firmware text output to the screen

;Load the BASIC program
load_file:
    ld hl,filename              ;HL = filename address
    ld de,&c000                 ;DE = file buffer address
    ld b,12                     ;B = length of filename
    call &bc77                  ;Open the file; on exit, BC contains file
                                ;length
    ld hl,&170                  ;BASIC program starts at &170
    push hl                     ;Store start address of BASIC program
    add hl,bc                   ;Calculate address of last byte of BASIC
    dec hl                      ;program
    ld (basic_prog_end_addr),hl ;Store it for use later
    pop hl                      ;Get start address of BASIC program
    call &bc83                  ;Read the contents of the file
    call &bc7a                  ;Close the file

;Set up a matrix table for characters 240-255 to be redefined
    ld de,240                   ;DE = first character in matrix table
    ld hl,(last_byte_addr)      ;HL = last usable byte of RAM by BASIC
    ld bc,16*8                  ;16 characters in table, 8 bytes for each
                                ;character
    sbc hl,bc                   ;Calculate value of HIMEM
    push hl                     ;Store it
    inc hl                      ;Start address of matrix table is the byte
                                ;following HIMEM
    call &bbab                  ;Initialise the matrix table

;Check which version of BASIC is being used
    ld c,0                      ;0 = BASIC ROM number
    call &b90f                  ;Select the BASIC ROM
    ld hl,(basic_prog_end_addr) ;Get end address of BASIC program
    pop de                      ;Get value of HIMEM (now in DE)
    ld bc,(last_byte_addr)      ;BC = last usable byte of RAM
    ld a,(&c002)                ;Read the version number
    and a                       ;Is it 0 (i.e. CPC464 BASIC)?
    jr z,start_basic_program_cpc464

;BASIC 1.1 is being used
    ld (&ae66),hl               ;Store the end address of the BASIC program
    ld (&ae68),hl               ;four times
    ld (&ae6a),hl
    ld (&ae6c),hl
    ex de,hl                    ;Now HL = value of HIMEM
    ld (&ae5e),hl               ;Store HIMEM
    ld (&ae60),bc               ;Store last usable byte of RAM

    cp 1                        ;Is a CPC664 being used (version 1)?
    jp z,&ea7d                  ;Yes
    jp &ea78                    ;No, so run the BASIC program

;BASIC 1.0 is being used
start_basic_program_cpc464:
    ld (&ae83),hl               ;Store the end address of the BASIC program
    ld (&ae85),hl               ;four times
    ld (&ae87),hl
    ld (&ae89),hl
    ex de,hl                    ;Now HL = value of HIMEM
    ld (&ae7b),hl               ;Store HIMEM
    ld (&ae7d),bc               ;Store last usable byte of RAM
    jp &e9bd                    ;Run the BASIC program

filename:
    db "PROGRAM .BAS"

basic_prog_end_addr:
    dw 0
last_byte_addr:                 ;Store the address of the last usable byte of
    dw 0                        ;RAM by BASIC

Hmmm... I should probably also upload this to CPCWiki somewhere... ::)

thanks for that brilliantly commented code!
..i dont know if ill use it... but i like it! :P

Powered by SMFPacks Menu Editor Mod