Jump to content
JAC!

XIO or similar to run COM/XEX from MyDos & SpartaDOS?

Recommended Posts

Hi,

 

Are there standard ways of loading and starting (normal INIADR/RUNADR handling) an executable file under MyDos & SpartaDOS?

Something like specific XIO commands or well defined vectors?

 

Peter/JAC!

Share this post


Link to post
Share on other sites

Great. With this info I foud here: http://www.mathyvannisselroy.nl/bflist.htm

MyDos: - XIO 40 is much slower then XIO 39. It's basically the same command. XIO 40 was added by Bob Puff for compatibility reasons (SpartaDOS uses XIO 40). But XIO 39 is about 3 times faster then XIO 40.

 

So should I rather use 39 under MyDOS or is this fixed in 4.5xx ?

Share this post


Link to post
Share on other sites

Great. With this info I foud here: http://www.mathyvann...y.nl/bflist.htm

MyDos: - XIO 40 is much slower then XIO 39. It's basically the same command. XIO 40 was added by Bob Puff for compatibility reasons (SpartaDOS uses XIO 40). But XIO 39 is about 3 times faster then XIO 40.

 

So should I rather use 39 under MyDOS or is this fixed in 4.5xx ?

That's not quite accurate to begin with. In the first place if you actually see this behavior then you are dealing with a pre 4.50 MyDOS of which 4.51 qualifies as it has this broken XIO 40 mode in particular. Puff then came along, fixed it and made 39 exactly the same as 40 in order to be compatable with Sparta and released it as 4.50. Everything after that is fixed for the broken XIO 40 mode. Blame Marslett for discontinuity in version numbers along with the broken XIO 40 mode. 4.51 predates 4.50. Puff came on board for 4.50 and fixed a LOT of these kinds of bugs.

 

What you should have been looking at while at that site was the 4.50 tech.doc from which I quote:

 

To load a program into memory, the address of the file name

string is stored into the buffer address, and a value of 4, 5, 6 or 7

is stored into the AUX1 field. If AUX1 is 4, both the initialization

routines and the run address are executed after closing the IOCB, but

before returning to the calling program. If AUX1 is 5, the

initialization routines are disabled, but the program will be run. If

AUX1 is 6, the initialization routines will be run, but the program

execute address will be loaded and ignored. If AUX1 is 7, the text of

the program will be loaded into memory, but no other activity will be

performed. CIO function code 40 performs the exact same function as

this (39).

 

Autorun.sys files are loaded with only the init vector active so whatever file you had in mind to autorun may need it's vectors played with.

 

Sparta as far as I know has nothing like this at all. It will ignore any and all run or init vectors and just run the file from it's first byte location after loading it into memory.

Share this post


Link to post
Share on other sites

Thanks a lot, but that would mean neiter variant of the command on neiter DOS is compatible with DOS 2.5?

BLOCK,INI1,BLOCK,INI2,BLOCK,RUN

 

would be INI2,RUN under MyDos according to the text (IOCB can only be closed after reading the whole file).

And Spartados does not support INI/RUN? ... Walter/Draco...?

Edited by JAC!

Share this post


Link to post
Share on other sites
Sparta as far as I know has nothing like this at all. It will ignore any and all run or init vectors and just run the file from it's first byte location after loading it into memory.

 

Complete nonsense. XIO 40 in SpartaDOS does normal binary load which means that init and run vectors are used as usual. The only difference is that when a binary file DOES NOT contain a run vector, it will be executed from the beginning.

Share this post


Link to post
Share on other sites

Thanks drac030 and 1050, that's what I expected. And I also verfied the the ICOB is still open during INADR calls and only closed for RUNADR in MyDOS when using AUX1=4. I guess the writing in the document was just a bit imprecise. So everything works fine here now with XIO 40.

Edited by JAC!

Share this post


Link to post
Share on other sites

Is there a way of launching a disk based .EXE after wiping DOS from memory?

 

I've tried reading the file into memory with the intention of calling its start location, but the load process overwrites the code that I am using to read it in. :?

Share this post


Link to post
Share on other sites

I've tried reading the file into memory with the intention of calling its start location, but the load process overwrites the code that I am using to read it in. :?

 

It that an arbitrary XEX or your own code? If it is your own, the best is to combine everything into one XEX.

In any case, you have to plan your memory layout accordingly.

And if you wipe DOS, how do you load the file?

Share this post


Link to post
Share on other sites

hey that gif is an mp4.. wtf is giphy doing? I think Arnold needs to have a talk with them!

 

Nice none the less

 

one more day till the start of looking back into projects...

Edited by _The Doctor__

Share this post


Link to post
Share on other sites

 

It that an arbitrary XEX or your own code? If it is your own, the best is to combine everything into one XEX.

In any case, you have to plan your memory layout accordingly.

And if you wipe DOS, how do you load the file?

It's actually a Rastaconverter image. The idea is to display the image (by running the executable) after the player has successfully completed the game. I would need to initiate a process that is completely separate from my code.

Share this post


Link to post
Share on other sites

Your best bet for a RC image might be to use compression. The code section tends to have lots of NOPs and repeated sequences to you might crunch down to about half the size or less.

Share this post


Link to post
Share on other sites

I like the sound of this - can you please provide a bit more detail? (my skill level floats somewhere above basic but below assembler)

 

I prepared a quick example of how you can use the xBOOT functions to load and decompress on the fly a packed binary file (rastaconverter/ packed LZ4). exactly the same (and even faster) can be done with xBIOS.

 

the problem is that you wanted for Sparta DOS and xBIOS does not support the SparaDOS filesystem. only AtariDOS / MyDOS / SuperDOS / BiboDOS etc.

test-normal.atr

test-lz4.atr

  • Like 3

Share this post


Link to post
Share on other sites

 

I prepared a quick example of how you can use the xBOOT functions to load and decompress on the fly a packed binary file (rastaconverter/ packed LZ4). exactly the same (and even faster) can be done with xBIOS.

 

the problem is that you wanted for Sparta DOS and xBIOS does not support the SparaDOS filesystem. only AtariDOS / MyDOS / SuperDOS / BiboDOS etc.

 

Thank you for the examples! Unfortunately xBIOS would consume too much memory.

 

I am trying to load and run an external executable file from within my program. As that I have already wiped out DOS, using a standard call is not an option. Is there a (relatively) simple way to run an executable from disk by either by filename or disk sector? I think I'd basically need to duplicate the functionality of the Binary Load function in the standard DUP.SYS

Share this post


Link to post
Share on other sites

 

Thank you for the examples! Unfortunately xBIOS would consume too

There will hardly be anything smaller. Maybe you can share more about the context and we find a way to not kill DOS at all. Using direct sector accesy is not a good idea for new stuff. It breaks on many modern devices.
  • Like 1

Share this post


Link to post
Share on other sites

DOS by Fox is shorter. it takes the same as xBOOT (384 bytes) its advantage is that it uses CIO but it does not decompress on the fly. And of course, it only works on Atari DOS and not on SpartaDOS

Share this post


Link to post
Share on other sites

Thank you for the examples! Unfortunately xBIOS would consume too much memory.

 

I am trying to load and run an external executable file from within my program. As that I have already wiped out DOS, using a standard call is not an option. Is there a (relatively) simple way to run an executable from disk by either by filename or disk sector? I think I'd basically need to duplicate the functionality of the Binary Load function in the standard DUP.SYS

If you are using an single or enhanced-density disk and if you can *raw* write your executable to consecutive sectors, 128 bytes per sector, then you could adapt my boot loader:

 

http://atariage.com/forums/topic/241044-writing-asm-programs-that-boot-from-disk/?p=3288846

 

You could probably get it to under 128 bytes of code. But note that raw writing the executable means there will be no chaining info in those sectors. This means DOS will not be able to read the file. Ideally you should mark those sectors as used in the VTOC so that DOS doesn't try to use them.

  • Like 1

Share this post


Link to post
Share on other sites
xxl, on 14 Jan 2019 - 11:21 AM, said:

DOS by Fox is shorter. it takes the same as xBOOT (384 bytes) its advantage is that it uses CIO but it does not decompress on the fly. And of course, it only works on Atari DOS and not on SpartaDOS

xBoot is 384 bytes? That works - I thought it was around 6K.

 

Question #2 - is it possible to load the xBIOS file into memory, execute it and then have access to the functions like "xBIOS_LOAD_BINARY_FILE" or do I need to boot from it?

Share this post


Link to post
Share on other sites

xBoot is 384 bytes? That works - I thought it was around 6K.

 

Question #2 - is it possible to load the xBIOS file into memory, execute it and then have access to the functions like "xBIOS_LOAD_BINARY_FILE" or do I need to boot from it?

 

 

xBoot - 384 bytes (at start, reusing it 256 maybe)

xBios - 1024 bytes (1K)

 

2. you can boot DOS, load xB from DOS - xB loads xautorun file (your program) -- xB supports many varieties of DOS filesystem, you need to run xB to configure&relocate itself according to the preferences of the coder.

  • Like 1

Share this post


Link to post
Share on other sites

This might help you, when you decide to use your own implementation.

If you remove cassette-specific stuff (motor control fiddling) and the initialization code (after the STARTUP label), you have your own binary load routine (using CIO device). This loads Atari DOS 2 binary load files.

I am sure more experienced coders would be able to shorten the routine.

;===============================================================================
;TURGEN SYSTEM - STDBLOAD 2a
;Binary loader for standard (FSK) tape records

;The author has placed this work in the Public Domain, thereby relinquishing all
;copyrights. Everyone is free to use, modify, republish, sell or give away this
;work without prior consent from anybody.

;This loader uses the "trailing EOF record trick" - Last 128 bytes of the
;loader are in the EOF block. These 128 bytes are moved from the cassette
;buffer to the intended memory location. The trick allows this loader to be
;only 4 records long

;The loader is ROM OS agnostic

;Using the LDRTYPE symbol, this loader can be assembled 
;to either boot (LDRTYPE=0) or binary (LDRTYPE=1) file. 
;===============================================================================

          .INCLUDE "equates.asm"
.IF LDRTYPE=0          
          LDR_START=[2048-24]
.ELSE
          LDR_START=2048
.ENDIF
          
          
          CIO1_OP   =$0342+16
          CIO1_STAT =$0343+16
          CIO1_BUFLO=$0344+16
          CIO1_BUFHI=$0345+16
          CIO1_LENLO=$0348+16
          CIO1_LENHI=$0349+16
          CIO1_AUX1 =$034A+16
          CIO1_AUX2 =$034B+16
          
          CIO0_OP   =$0342
          CIO0_STAT =$0343
          CIO0_BUFLO=$0344
          CIO0_BUFHI=$0345
          CIO0_LENLO=$0348
          CIO0_LENHI=$0349
          CIO0_AUX1 =$034A
          CIO0_AUX2 =$034B

          *=[LDR_START]
;-------------------------------------------------------------------------------
; Boot header
;-------------------------------------------------------------------------------
.IF LDRTYPE=0
BOOTHEAD  .BYTE 0
          .BYTE 3
          .WORD [LDR_START]
          .WORD FAKEINIT
          
          lda  #60                ;Motor off
          sta  PACTL
          ldx  #255               ;Clear pushdown store
          txs
;-------------------------------------------------------------------------------
; Move last portion of the loader code from cassette buffer
;-------------------------------------------------------------------------------
RELO_P2   ldx  #128               ;Move 128 bytes of the EOF block
RELO_P2_L lda  [1024-1],X         ;from cassette buffer
          sta  [LDR_START+384-1],X  ;to the intended place
          dex  
          bne  RELO_P2_L
.ENDIF         
;-------------------------------------------------------------------------------
; Loader mainline code
;-------------------------------------------------------------------------------
BL000     jsr  STARTUP            ;Display program name

BLTOP     lda #1                  ;Rest flags (first segment + no binary header)
          sta BLF_FIRST           
          sta BLF_NOBIN
          
          jsr FCLOSE
          jsr FOPEN               ;Call subroutine that opens C: file
          lda CIO1_STAT           ;Check for error
          bpl GETSEG              ;No error, continue
          jsr ERRHNDL             ;If error occured, go to handle it
          jmp BLTOP               ;Then start again

;-------------------------------------------------------------------------------
; Read a segment 
;-------------------------------------------------------------------------------
GETSEG    lda #<FAKEINIT          ;Set fake INIT vector to RTS
          sta 738
          lda #>FAKEINIT
          sta 739

;-------------------------------------------------------------------------------
; Get segment header
;-------------------------------------------------------------------------------
GS_STRTA  lda #<BLSEGHEAD         ;Read first two bytes of segment header
          sta CIO1_BUFLO
          lda #>BLSEGHEAD
          sta CIO1_BUFHI
          lda #2
          sta CIO1_LENLO
          lda #0
          sta CIO1_LENHI
          jsr GETBLK
           
          lda #255                ;Check for 255 255
          cmp BLSEGHEAD
          bne GS_ENDA
          cmp BLSEGHEAD+1
          bne GS_ENDA             ;If 255 255 not found, continue
          
          lda #0
          sta BLF_NOBIN
          jmp GS_STRTA            ;And then start over
          
          
GS_ENDA   lda #<[BLSEGHEAD+2]     ;Get rest of the segment header 
          sta CIO1_BUFLO
          lda #>[BLSEGHEAD+2]
          sta CIO1_BUFHI
          lda #2
          sta CIO1_LENLO
          lda #0
          sta CIO1_LENHI
          jsr GETBLK
          
;-------------------------------------------------------------------------------
; Processing specific for the first segment
; 255 255 header check
; RUNAD is set to point to the first segment
;-------------------------------------------------------------------------------
          lda BLF_NOBIN          ;Check if 255 255 header was found
          beq GS_FSRUN           ;It was, we can continue
          jmp ERRNOBIN           ;If not, we signalize an error and continue

GS_FSRUN  lda BLF_FIRST          ;Is this the first segment
          beq GS_CALCLN          ;No, just continue
          lda #0                 ;Reset first segment indication
          sta BLF_FIRST          ;RUNAD points to this segment
          lda BLSEGHEAD
          sta 736
          lda BLSEGHEAD+1
          sta 737
;-------------------------------------------------------------------------------
; Calculate length of the segment           
;-------------------------------------------------------------------------------          
GS_CALCLN sec                    ;Subtract start address from end address
          lda BLSEGHEAD+2        
          sbc BLSEGHEAD+0
          sta CIO1_LENLO
          bcs GS_LENHI
          dec BLSEGHEAD+3
GS_LENHI  sec
          lda BLSEGHEAD+3
          sbc BLSEGHEAD+1
          sta CIO1_LENHI
          
          clc                    ;Increase the difference by 1 to get length
          lda CIO1_LENLO
          adc #1
          sta CIO1_LENLO
          bcc GS_GETD
          inc CIO1_LENHI
;-------------------------------------------------------------------------------          
;Read segment data          
;-------------------------------------------------------------------------------          
GS_GETD   lda BLSEGHEAD
          sta CIO1_BUFLO
          lda BLSEGHEAD+1
          sta CIO1_BUFHI
          jsr GETBLK
;-------------------------------------------------------------------------------
; INIT segment handling
;-------------------------------------------------------------------------------          
          lda 738                ;Check if there was real INIT segment
          cmp #<FAKEINIT
          bne REALINI
          lda 739
          cmp #>FAKEINIT
          beq POSTINI
          
REALINI   lda #60                ;Switch off the motor
          sta PACTL 
          jsr DOINIT             ;Execute INIT segment code
          lda #52                ;Switch on the motor
          sta PACTL

POSTINI   jmp GETSEG             ;Get another segment

;===============================================================================
;Subroutine that gets a blocks using CIO. Buffer address and length of
;the block must be set by the caller.
;===============================================================================
GETBLK    ldx #16                   ;Channel 1
          lda #7                    ;Requesting CIO READ operation
          sta CIO1_OP             
          jsr CIOV                  ;Call CIO
          lda CIO1_STAT             ;Check for error
          bmi GBERR                 ;Error occured - handle it
          rts
          
GBERR     cmp #136                  ;Is this EOF ?
          bne GBERR_S               ;No - handle error
          ldx #255                  ;Yes, this is EOF
          txs                       ;Clear stack
          jsr FCLOSE                ;Close file
          jmp (736)                 ;Run the program
        
GBERR_S   jmp ERRHNDL
 
;===============================================================================
;Emulation of JSR(738)
;===============================================================================
DOINIT    jmp (738)
FAKEINIT  rts
;===============================================================================
;Main data area
;===============================================================================
BLSEGHEAD   .BYTE 0,0,0,0        ;Segment header and position pointer
BLF_FIRST   .BYTE 0              ;First segment to be loaded
BLF_NOBIN   .BYTE 0              ;No binary file header found yet

CDEV        .BYTE "C:",155       ;File name
;===============================================================================
;Subroutine that closes file
;===============================================================================
FCLOSE    ldx #16
          lda #12         ;Requesting CIO CLOSE operation with code 12
          sta CIO1_OP    
          jsr CIOV        ;Call CIO
          rts             
;===============================================================================
;Subroutine that opens file
;===============================================================================
FOPEN     ldx #16                ;IOCB 1
          lda #3                 ;Requesting CIO OPEN operation with code 3
          sta CIO1_OP
          lda #4                 ;Auxiliary value 4 - open for reading
          sta CIO1_AUX1
          
          lda #12                ;And also simulate key press
          sta CH                 
                       
          lda #128               ;Auxiliary value 128 - short IRGs
          sta CIO1_AUX2
          lda #<CDEV             ;Buffer- DEVICE:FILENAME ("C:")
          sta CIO1_BUFLO
          lda #>CDEV
          sta CIO1_BUFHI
          
          jsr CIOV               ;Call CIO
          rts 
;===============================================================================
;Error handling
;===============================================================================
ERRHNDL  lda #$24                ;I/O error - red background
         jsr ERRSIG
         jmp COLDSV              ;Cold start
         
ERRNOBIN lda #$0E                ;Not a binary file - white background
         jsr ERRSIG
         jmp WARMSV              ;Warm start         

;===============================================================================
; Auxiliary routines for error handling
;===============================================================================  
ERRSIG   sta COLOR4              ;Signalize error by changing background
         sta COLOR2
         sta COLBK
         sta COLPF2
         lda #60                 ;Switch off the motor
         sta PACTL  
         jsr WFORKEY
         rts
         
WFORKEY  lda #255                ;Wait for any key
         sta 764
WFORKEYL lda 764
         cmp #255
         beq WFORKEYL
         rts
;===============================================================================
; Loader startup
;===============================================================================
STARTUP   lda #0                  ;Reset cold start flag
          sta 580
          lda #1                  ;Indicate disk boot succeeded
          sta 9
          jsr DINI
          
          lda #<DINI
          sta DOSINI
          lda #>DINI
          sta DOSINI+1
          
          lda #148                ;Set background
          sta COLOR2
          lda #3                  ;Noisy or silent I/O
          sta SOUNDR
          
          ldx #0                  ;Channel 0
          lda #9                  ;Requesting PRINT
          sta CIO0_OP
          lda #<PROGTITLE
          sta CIO0_BUFLO
          lda #>PROGTITLE
          sta CIO0_BUFHI
          lda #<[PROGNEND-PROGTITLE]
          sta CIO0_LENLO
          lda #>[PROGNEND-PROGTITLE]
          sta CIO0_LENHI
          jsr CIOV                ;Call CIO
          
DINI      lda #<BLTOP
          sta DOSVEC
          lda #>BLTOP
          sta DOSVEC+1
          rts

PROGTITLE .BYTE 125               ;Clear screen
PROGNAME  .BYTE 32                ;34 characters for program name
          .REPT [33]              
          .BYTE 32
          .ENDR
          .BYTE 32                ;Extra blank
          .BYTE "!"          ;Inverse video exclamation mark
PROGNEND  
          
;===============================================================================
; RUN segment
;===============================================================================
.IF LDRTYPE=1
          *=736
          .BYTE <BL000,>BL000
.ENDIF          

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...