I have absolutely no idea what I'm doing.

Get technical support from the community & developers with specific X16 programs if you can't find the solution elsewhere
(for general non-support related chat about programs please comment directly under the program in the software library)
Post Reply
User avatar
Daedalus
Posts: 229
Joined: Fri Nov 11, 2022 3:03 am

I have absolutely no idea what I'm doing.

Post by Daedalus »

I'm trying to implement a rudimentary communication channel to the sdcard's command channel to get useful info like dir listings, etc.
But I have absolutely no clue what I am doing.

This is what my code is doing:

Code: Select all

dir_test:
    bra @start

        @char_in:   .byte 0
    @start:
	lda #8
	jsr LISTEN ; ($ffb1)
	lda #15
	jsr SECOND ; ($ff93)
	lda #'$'
	jsr CIOUT ; ($ffa8)
	lda #'='
	jsr CIOUT ; ($ffa8)
	lda #'C'
	jsr CIOUT ; ($ffa8)
	lda #$0d
	jsr CIOUT ; ($ffa8)
	jsr UNLSN ; ($ffae)

	lda #8
	jsr TALK; ($ffb4)
	lda #15
	jsr TKSA ; ($ff96)
    ldx #100   
        @loop:
        jsr ACPTR; ($ffa5)
        sta @char_in 
        jsr XSH_ADD_CHAR
        lda @char_in 
        dex
        bne @loop

    jsr UNTALK ; ($ffab)

    rts


The call to XSH_ADD_CHAR is a hook back to the terminal that inserts the characters. (Printable ones display, $0d goes to the next line.)
This is what happens:
dir attempt.png
dir attempt.png (22 KiB) Viewed 6470 times
DragWx
Posts: 345
Joined: Tue Mar 07, 2023 9:07 pm

Re: I have absolutely no idea what I'm doing.

Post by DragWx »

You might not need to terminate your command with $0D, at least I can't find any mention of needing to do so in any of the docs.
User avatar
Daedalus
Posts: 229
Joined: Fri Nov 11, 2022 3:03 am

Re: I have absolutely no idea what I'm doing.

Post by Daedalus »

Yeah, it turns out you don't do it that way, you just have to load a special file named "$" to get the files in the directory, or "$=C" to get the current directory name.

I tried:

Code: Select all

dir_test:
    bra @start

        @count:   .byte 0
        @char_in:   .byte 0
    @start:
	lda #2
	ldx #8
	ldy #0
	jsr SETLFS

	lda #3
	ldx #<test_line ; The filename... "$" or "$=C"
	ldy #>test_line
	jsr SETNAM

	jsr OPEN

	ldx #2
	jsr CHKIN
	stz @count
    ldx #80
	    @loop:
        jsr ACPTR
		sta @char_in
        jsr XSH_ADD_CHAR
		dex
		bne @loop

	lda #2
	jsr CLOSE
	rts
I got this! I just need to figure out the formatting of the data.
dir_test_2.png
dir_test_2.png (18.46 KiB) Viewed 6448 times
User avatar
Daedalus
Posts: 229
Joined: Fri Nov 11, 2022 3:03 am

Re: I have absolutely no idea what I'm doing.

Post by Daedalus »

Ok. I'm getting this... to change directories, I use the "LISTEN : TALK" mechanic I tried first with commands like "CD:/"
User avatar
Daedalus
Posts: 229
Joined: Fri Nov 11, 2022 3:03 am

Re: I have absolutely no idea what I'm doing.

Post by Daedalus »

So I figured out the basic format of the directory file by trying and searching on the web.

Then I made the shell display any non-printable characters as hexadecimal with brackets around it, like [a5], that makes it easier to tell the difference between those and the printable characters like spaces or numbers. I also put all the command programs into a directory called "bin" so they would be out of the way but easy to find.

I need to auto-append the path to the commands yet, instead I'm just typing the path every time like a stooge:
directory test 3.png
directory test 3.png (47.96 KiB) Viewed 6383 times
The /bin/ls command is the file list. The code that displays the list is: (Note: It's not pretty! It's in the "barely works" state.)

Code: Select all

.include "charmap.inc"

.org $A000
.segment "CODE"

XSH_ADD_CHAR    = $0810

SETLFS				= $ffba
SETNAM				= $ffbd
OPEN				= $ffc0
CHKIN				= $ffc6
CLOSE 				= $ffc3
CHRIN				= $ffcf

LISTEN              = $ffb1
SECOND              = $ff93
UNLSN               = $ffae
CIOUT				= $ffa8

TALK    = $ffb4
TKSA    = $ff96
UNTALK  = $ffab
ACPTR   = $ffa5

jmp dir_test

pwd_msg:    .byte "A:/ (This is the pwd command.)",0

test_line:	.byte "CD:CV"
test_line2:	.byte "$=C"
test_line3:	.byte "$"

dir_test:
    bra @start

        @count:   .byte 0
        @char_in:   .byte 0
    @start:
	lda #2
	ldx #8
	ldy #0
	jsr SETLFS

	lda #1
	ldx #<test_line3
	ldy #>test_line3
	jsr SETNAM

	jsr OPEN

	ldx #2
	jsr CHKIN
	stz @count

	jsr print_host

	@loop:
	jsr print_line
	bne @loop

	lda #2
	jsr CLOSE
	rts

print_host:
	; 6 byte header
	jsr ACPTR
    jsr XSH_ADD_CHAR
    jsr ACPTR
    jsr XSH_ADD_CHAR
    jsr ACPTR
    jsr XSH_ADD_CHAR
    jsr ACPTR
    jsr XSH_ADD_CHAR

	; line number
    jsr ACPTR
    jsr XSH_ADD_CHAR
    jsr ACPTR
    jsr XSH_ADD_CHAR

	; All other chars.
	    @loop:
        jsr ACPTR
        tax
		jsr XSH_ADD_CHAR
		txa
		bne @loop

	lda #$0d
	jsr XSH_ADD_CHAR
	rts

print_line:
	bra @start

		@cur_char:	.byte 0
	@start:
    jsr ACPTR
	sta @cur_char
    jsr XSH_ADD_CHAR
	lda @cur_char
	bne @continue
	lda #0
	rts

	@continue:
 ;   jsr XSH_ADD_CHAR
    jsr ACPTR
    jsr XSH_ADD_CHAR

	; line number
    jsr ACPTR
    jsr XSH_ADD_CHAR
    jsr ACPTR
    jsr XSH_ADD_CHAR

	; All other chars.
	    @loop:
        jsr ACPTR
		tax
        jsr XSH_ADD_CHAR
		txa
		bne @loop

	lda #$0d
	jsr XSH_ADD_CHAR

	lda #1
	rts	
The format for each line is 4 command bytes on the first line, then 2 on each line after. The 2 bytes after that are the line number, which is used to hold the file size (in sectors), then the name and type, padded with spaces for formatting on the BASIC screen. Finally, a [00] byte that indicates an end of line. After the last line, a single [00] indicates the end of the list. I think the [12] on the first line tells the BASIC screen to display that line in inverse characters.
User avatar
Daedalus
Posts: 229
Joined: Fri Nov 11, 2022 3:03 am

Re: I have absolutely no idea what I'm doing.

Post by Daedalus »

There is a difference between the commands that are intended to operate as "terminal commands" like ls and cd, and commands that are programs like xsh (The program that runs the shell.) the terminal commands .org at $a000, while the programs .org at .080d and have the BASIC lead in header like any other program.

To run a program from the shell, (For example, it can run itself.) it uses a terminal command called "launch" that runs at $a000, then after resetting int handlers to default, loads the program and executes it by doing jsr $080d

If the program then eventually exits cleanly with a final rts, AND banked RAM hasn't been changed too much (Yeah, right.) the terminal command will still be there and can restart the shell.

So, before I had absolutely no idea what I was doing! But with diligence, lots of web surfing, and LOTS of trying stupid looking code I had no idea would work... and using the debugger A LOT, I figured a lot of this puzzle out.

So now I know! And knowing is half the battle!
TomXP411
Posts: 1785
Joined: Tue May 19, 2020 8:49 pm

Re: I have absolutely no idea what I'm doing.

Post by TomXP411 »

Daedalus wrote: Sat Jun 03, 2023 9:30 pm Yeah, it turns out you don't do it that way, you just have to load a special file named "$" to get the files in the directory, or "$=C" to get the current directory name.

I got this! I just need to figure out the formatting of the data.
it's actually a BASIC program listing (although it's slightly broken). I've actually spent a lot of time dealing with the directory, in my attempts to build a file browser.

Start of file:
0-1: load address ($01 $08)

Then for the first line:
2-3: "next line" pointer. Ignore.
4-5: 16-bit integer. Should be $00 $00
6-n: directory header
n+1: Should be $00

Then each additional line:
0-1: "next line" pointer. Ignore.
2-3: 16-bit integer. This is the number of blocks in the file. One block is 254 bytes of data.
The rest of the line is what you see on the screen:
4 spaces
Quote symbol
filename text
Quote sumbol
several spaces
"DIR" or "PRG" (Commodore disk drives have additional codes, not listed here)
$00

Since a BASIC line always ends with a $00, you can read a directly line by:
Read and discard 2 bytes
Read 2 bytes and print as a decimal value.
Read and print up to the $00 character.
Discard the $00
Print a CR ($0D).
Repeat until you get $00 $00 $00, or the file ends.
User avatar
Daedalus
Posts: 229
Joined: Fri Nov 11, 2022 3:03 am

Re: I have absolutely no idea what I'm doing.

Post by Daedalus »

Start of file:
0-1: load address ($01 $08)

Of course! $0801! I didn't even make that connection.

Then the next two in the first line, and the first two or each additional line are the "next line" pointer? They're all the same... 01 01. Ok. Into the ignore pile.

So the 12 at location 6 in the first line is part of the name... I had surmised it was what was making it inverted.
TomXP411
Posts: 1785
Joined: Tue May 19, 2020 8:49 pm

Re: I have absolutely no idea what I'm doing.

Post by TomXP411 »

Daedalus wrote: Mon Jun 05, 2023 3:39 am Then the next two in the first line, and the first two or each additional line are the "next line" pointer? They're all the same... 01 01. Ok. Into the ignore pile.
Yeah, the "next line" pointer is part of the binary data of a BASIC program, but it's basically ignored when a program is read from disk. The reason being that a program can be moved around in memory, so these pointers are re-computed on the fly.

So while the value is not correct, the $0101 does make for a convenient touchstone value when writing your program; however, I don't remember what a 1541 or other drive will report in that spot, so don't count on that always being the same value.

As far as the entry text: it's important to remember that the line length is variable. Even though it has a set minimum length, the line can extend if the filename is longer than 16 characters. So make sure to look for that $00 line terminator.
mortarm
Posts: 302
Joined: Tue May 16, 2023 6:21 pm

Re: I have absolutely no idea what I'm doing.

Post by mortarm »

TomXP411 wrote: Mon Jun 05, 2023 2:40 am Start of file:
0-1: load address ($01 $08)

Then for the first line:
2-3: "next line" pointer. Ignore.
4-5: 16-bit integer. Should be $00 $00
6-n: directory header
n+1: Should be $00

Then each additional line:
0-1: "next line" pointer. Ignore.
2-3: 16-bit integer. This is the number of blocks in the file. One block is 254 bytes of data.
The rest of the line is what you see on the screen:
4 spaces
Quote symbol
filename text
Quote sumbol
several spaces
"DIR" or "PRG" (Commodore disk drives have additional codes, not listed here)
$00

Since a BASIC line always ends with a $00, you can read a directly line by:
Read and discard 2 bytes
Read 2 bytes and print as a decimal value.
Read and print up to the $00 character.
Discard the $00
Print a CR ($0D).
Repeat until you get $00 $00 $00, or the file ends.
Love this post! Always wondered how a BASIC program was stored. Now let's see what kind of Frankenstein-@#$% I can do with it. Heh heh heh! :twisted:
Post Reply