Assembly and Files ------------------ This file is specific to the Apple II series of computers running ProDOS. It explains how to make simple use of disk files via assembly language. ================================================================================ 1. MLI and commands 2. Detailed command descriptions 3. Programming example MLI and commands ---------------- Most disk access from within an Apple II assembly language program uses the machine language interface supplied by the ProDOS operating system. Commands consist of a call to $BF00 followed by a table of command parameters. If ProDOS returns a value it is returned in a location within this table. MacQForth implements a useful subset of the standard ProDOS commands. The general form of a command is: JSR $BF00 ; call ProDOS to do the command (command-number) (address-of-parameter-table) (execution returns to here when finished) If an error happens, the carry flag is set and the accumulator contains the error code. MacQForth returns 0 if no error or the absolute value of the corresponding Macintosh file error number if an error happened. The contents of the parameter table vary from command to command, but a general form is: (number-of-parameters) (parameters) . . So, a possible assembly language calling sequence to read some data from an open file (file 0) might be: ldx #$00 ldy #$10 sty params+4 stx params+5 ; setup number of bytes to read (16) jsr $BF00 ; call ProDOS .BYTE $CA ; ProDOS command number = CA (read) .WORD params ; address of parameter table, lo/hi bcs error ; carry set, error . . params .BYTE $04 ; number of parameters for a read .BYTE $00 ; file reference number, 0, 1, 2 in MacQForth .WORD BUFFER ; pointer to data buffer .WORD $0000 ; requested number of bytes to read, fill in .WORD $0000 ; number actually read, returned by ProDOS The following ProDOS commands are available and their parameters are outlined below: $C0 = create a new file $C1 = destroy an existing file $C4 = get file info (a dummy command, do not use) $C8 = open a file (reference numbers 0, 1, or 2) $CA = read from a file $CB = write to a file $CC = close a file $CE = position file marker $65 = bye, cause MacQForth to quit, use to quit the application from within an assembly language program Note: Do not use "/" as the directory separator. Instead, use ":" which is the normal Mac separator. Remember that pathnames are stored as length/text. So, the pathname for the file "ABC" is stored (in decimal) as 3,65,66,67. (Minus commas, of course!) Detailed command descriptions ----------------------------- Command parameters marked as _required_ are necessary for MacQForth, those marked as _ignored_ are not. Any value can be in the _ignored_ field. If a parameter is returned it is indicated as a (result) and space must be made for the value. ** Create a new file command number $C0 parameters: 0 (number-of-parameters) (7) _required_ +1 (pointer to pathname) _required_ +3 (access code) _ignored_ +4 (file type code) _ignored_ +5 (auxilliary type code) _ignored_ +7 (storage type) _ignored_ +8 (date of creation) _ignored_ +10 (time of creation) _ignored_ ** Destroy an existing file command number $C1 parameters: 0 (number-of-parameters) (1) _required_ +1 (pointer to pathname) _required_ ** Open an existing file command number $C8 parameters: 0 (number-of-parameters) (3) _required_ +1 (pointer to pathname) _required_ +3 (pointer to i/o buffer) _required_** +5 (reference number, 0, 1, 2) _required_ (result) ** MacQForth is trailored to running QForth. Therefore, you can use at most three files corresponding to reference numbers 0, 1, and 2. MacQForth determines which file QForth wants to use by the address of this buffer. The buffer itself is unused but it _must_ be one of the following addresses, in lo/hi format, File 0 = 00:A6 File 1 = 00:A2 File 2 = 00:9E ** Read from an open file command number $CA parameters: 0 (number-of-parameters) (4) _required_ +1 (file reference number) _required_ +2 (pointer to data buffer) _required_ +4 (requested number of bytes) _required_ +6 (number actually read) _required_ (result) ** Write to an open file command number $CB parameters: 0 (number-of-parameters) (4) _required_ +1 (file reference number) _required_ +2 (pointer to data buffer) _required_ +4 (requested number of bytes) _required_ +6 (number actually written) _required_ (result) ** Close an open file command number $CC parameters: 0 (number-of-parameters) (1) _required_ +1 (file reference number) _required_ ** Position file marker within an open file command number $CE parameters: 0 (number-of-parameters) (2) _required_ +1 (file reference number) _required_ +2 (file position, *3* bytes) _required_ ** Bye command number $65 parameters: 0 (number-of-parameters) (4) _ignored_ +1 (quit type code) _ignored_ +2 (pointer to quit code) _ignored_ +4 (a reserved value) _ignored_ +5 (a reserved pointer) _ignored_ Programming example ------------------- A simple programming example to create a new file named "ABC" and write some text to it. Also in FILE.S in the DEMO folder. ; ; MakeFile -- creates a file and writes some data. Ignores errors. ; *= $300 ; create the file "ABC" lda #$01 ; setup for 'create' sta PARAMS lda #<NAME ; low byte of name address sta PARAMS+1 lda #>NAME ; high byte of name address sta PARAMS+2 lda #$C0 ; create command sta MLI+3 ; put in table jsr MLI ; create the file ; open the file lda #$03 sta PARAMS ; adjust number of parameters, name already set lda #$00 sta PARAMS+3 lda #$A6 sta PARAMS+4 ; use file 0 lda #$C8 ; open command sta MLI+3 jsr MLI ; open the file ; write to the file lda #$04 sta PARAMS lda PARAMS+5 ; get reference number returned by open sta PARAMS+1 ; and put in for write sta REF ; and save for close lda #<STRING sta PARAMS+2 ; pointer to data lda #>STRING sta PARAMS+3 lda #$05 ; number of bytes to write sta PARAMS+4 lda #$00 sta PARAMS+5 lda #$CB ; write command sta MLI+3 jsr MLI ; write the data ; close the file lda #$01 sta PARAMS lda REF ; put in reference number sta PARAMS+1 lda #$CC ; close command sta MLI+3 jsr MLI ; close the file rts ; and end ; call MLI MLI jsr $BF00 ; call ProDOS .byte $00 ; command number .word PARAMS ; address of parameter table rts ; data NAME .byte 3,"ABC" ; name of the file with length STRING .byte "Hello",0 ; data to write REF .byte $00 ; ProDOS reference number PARAMS .dbyt $0000 ; ProDOS parameter table .dbyt $0000 .dbyt $0000 .dbyt $0000