From a6f71701d9af1ce90355534642d574e3fd16b6f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carsten=20Elton=20S=C3=B8rensen?= Date: Tue, 1 Aug 2023 11:00:50 +0200 Subject: [PATCH] Argument passing, run user programs from disk, cosmetic changes --- Makefile | 4 +- dos/cmd.asm | 76 ++++++++++- dos/cmd_dir.asm | 25 +--- dos/cmd_dump.asm | 22 +-- dos/cmd_exec.asm | 2 - dos/cmd_external.asm | 314 +++++++++++++++++++++++++++++++++++++++++++ dos/cmd_keys.asm | 25 +--- dos/cmd_write.asm | 1 + dos/display.asm | 28 +++- dos/dos.asm | 67 ++------- dos/reader.asm | 5 +- dos/readline.asm | 45 ++++++- dos/strings.asm | 24 +++- 13 files changed, 493 insertions(+), 145 deletions(-) create mode 100755 dos/cmd_external.asm diff --git a/Makefile b/Makefile index 8593728..9690d49 100755 --- a/Makefile +++ b/Makefile @@ -15,11 +15,13 @@ DOS = \ dos/cmd_keys.asm \ dos/cmd_exec.asm \ dos/cmd_wifi.asm \ + dos/cmd_external.asm \ dos/strings.asm \ dos/display.asm \ dos/readline.asm \ dos/reader.asm \ - kernel/api.asm + kernel/api.asm \ + kernel/keys.asm COPT = -C -Wall -Werror -Wno-shadow -x --verbose-list -I . diff --git a/dos/cmd.asm b/dos/cmd.asm index 95ffb5e..ae5df78 100755 --- a/dos/cmd.asm +++ b/dos/cmd.asm @@ -17,7 +17,7 @@ cmd .namespace .mkstr nolist, "No drives found." .mkstr unknown, "Unknown command." .mkstr failed, "Command failed." - .mkstr help, "Enter 'help' for help." + .mkstr help, "Enter 'help' for help, 'about' for information about this software." .mkstr bad_drive, "Drive number must be in [0..7]." .mkstr no_drive, "Drive not found." @@ -38,6 +38,7 @@ words .namespace .align 256 base .null "" ; So offset zero is invalid help .null "help" +about .null "about" ls .null "ls" dir .null "dir" read .null "read" @@ -58,6 +59,7 @@ wifi .null "wifi" commands .word words.help, help + .word words.about, about .word words.ls, dir.cmd .word words.dir, dir.cmd .word words.read, read.cmd @@ -76,6 +78,66 @@ commands .word words.wifi, wifi.cmd .word 0 +about + jsr hardware + jsr ukernel + jsr fat32 + rts +hardware + phx + + lda #>_msg + ldx #<_msg + jsr strings.puts_zero + + plx + rts +_msg + .text $0a + .text "Foenix F256 by Stefany Allaire", $0a + .text "https://c256foenix.com/f256-jr",$0a + .text $0a, $00 + +ukernel + phx + + lda #>_msg + ldx #<_msg + jsr strings.puts_zero + + lda #$E0 + ldx #$08 + jsr strings.puts_zero + + jsr put_cr + jsr put_cr + + plx + rts +_msg + .text "TinyCore MicroKernel", $0a + .text "Copyright 2022 Jessie Oberreuter", $0a + .text "Gadget@HackwrenchLabs.com",$0a + .text "Built/revision: ",0 + +fat32 + phx + + ldx #<_msg + lda #>_msg + jsr strings.puts_zero + + plx + rts + +_msg + .text "Fat32 from https://github.com/commanderx16/x16-rom", $0a + .text "Copyright 2020 Frank van den Hoef and Michael Steil", $0a + .text $0a + .text "Simple DOS Shell, built ", DATE_STR, $0a + .byte $0 + + help lda #<_msg sta tmp+0 @@ -110,7 +172,8 @@ _msg .text "keys Demonstrates key status tracking.", $0a .text "exec <$hex> JSR to a program in memory (try $a015).", $0a .text "help Prints this text.", $0a - .text "wifi Configures the wifi access point." + .text "about Information about the software and hardware.", $0a + .text "wifi Configures the wifi access point.", $0a .byte $0 start @@ -261,6 +324,8 @@ _next inx bra _cmd _fail + ; Set up argument array for user programs + jsr readline.populate_arguments .if true ; See if it's the name of a binary stz kernel.args.buf+0 @@ -272,6 +337,13 @@ _fail lda #0 sta (kernel.args.buf),y jsr kernel.RunNamed +.endif +.if true + ; Try to load an external user program on disk, kernel.args.buf is already initialized + jsr external.cmd + bcs _unknown_cmd + rts +_unknown_cmd .endif ; If the chain failed, unknown command. lda #unknown_str diff --git a/dos/cmd_dir.asm b/dos/cmd_dir.asm index 4095264..904233a 100755 --- a/dos/cmd_dir.asm +++ b/dos/cmd_dir.asm @@ -52,6 +52,7 @@ cmd stz stop ; Set the drive + lda #1 ; Token #1 jsr readline.parse_drive sta kernel.args.directory.open.drive @@ -218,34 +219,14 @@ print_ext ; TODO: overlay the appropriate struct and read the members. lda buf+1 - jsr print_hex + jsr display.print_hex lda buf+0 - jsr print_hex + jsr display.print_hex rts -print_hex - pha - lsr a - lsr a - lsr a - lsr a - jsr _digit - pla - and #$0f - jsr _digit - rts -_digit - phy - tay - lda _digits,y - ply - jmp putc -_digits - .text "0123456789abcdef" - .send .endn diff --git a/dos/cmd_dump.asm b/dos/cmd_dump.asm index c479bce..cdc536e 100755 --- a/dos/cmd_dump.asm +++ b/dos/cmd_dump.asm @@ -25,7 +25,7 @@ cmd jmp reader.read_file print - jsr print_hex + jsr display.print_hex jsr print_space dec count bne _done @@ -39,26 +39,6 @@ print_space lda #' ' jmp putc -print_hex - pha - lsr a - lsr a - lsr a - lsr a - jsr _digit - pla - and #$0f - jsr _digit - rts -_digit - phy - tay - lda _digits,y - ply - jmp putc -_digits - .text "0123456789abcdef" - .send .endn diff --git a/dos/cmd_exec.asm b/dos/cmd_exec.asm index 5f32dfd..ded7e9c 100755 --- a/dos/cmd_exec.asm +++ b/dos/cmd_exec.asm @@ -2,8 +2,6 @@ exec .namespace - .mkstr desc, "This program shows the held status of keys. Press to quite." - .section dp addr .word ? .send diff --git a/dos/cmd_external.asm b/dos/cmd_external.asm new file mode 100755 index 0000000..5cd1436 --- /dev/null +++ b/dos/cmd_external.asm @@ -0,0 +1,314 @@ + .cpu "65c02" + +external .namespace + + .mkstr not_executable, "File is not executable." + + +header_t .struct +sig_f2 .byte ? +sig_56 .byte ? +blocks .byte ? +start_slot .byte ? +entry .word ? + .fill 4 +size .ends + + .section data +success .byte ? +stream .byte ? +remaining .word ? +when_done .word ? +header .dstruct header_t + .send + + + .section code + +cmd + ; Initialize to "no stream" + stz stream + + ; Indicate fail until we know better + stz success + + ; Set the drive + lda drive + sta kernel.args.file.open.drive + + ; Set the filename (conveniently aligned) + lda readline.tokens+0 + sta kernel.args.file.open.fname+0 + lda #>readline.buf + sta kernel.args.file.open.fname+1 + + ; Set the filename length + lda #0 ; Token #0 + jsr readline.token_length + beq _handle_not_found + sta kernel.args.file.open.fname_len + + ; Set the mode and open + lda #kernel.args.file.open.READ + sta kernel.args.file.open.mode + jsr kernel.File.Open + bcs _handle_not_found + + ; Fall through to event loop and load the executable + +_event_loop + jsr kernel.NextEvent + bcs _event_loop + + .if false + lda #'>' + jsr display.putchar + lda event.type + jsr display.print_hex + jsr put_cr + .endif + + lda event.type + + cmp #kernel.event.key.PRESSED + beq _handle_check_escape + + cmp #kernel.event.file.NOT_FOUND + beq _handle_not_found + cmp #kernel.event.file.ERROR + beq _handle_not_found + + cmp #kernel.event.file.OPENED + beq _handle_opened + cmp #kernel.event.file.DATA + beq _handle_data_read + cmp #kernel.event.file.CLOSED + beq _handle_file_closed + cmp #kernel.event.file.EOF + beq _handle_eof + + bra _event_loop + + +_handle_not_found + sec + rts + + +_handle_check_escape + lda event.key.raw + cmp #ESC + bne _event_loop + jmp _close_file + + +_handle_file_closed + lda success + beq _exit_good + jmp _start_program +_exit_good + clc + rts + + +_handle_opened + ; Read file header + lda event.file.stream + sta stream + + lda #
header + sta kernel.args.buf+1 + + lda #<_handle_header_read + sta when_done + lda #>_handle_header_read + sta when_done+1 + + lda #_handle_exe_read + sta when_done+1 + + jmp _start_read + + +_handle_exe_read + lda #$ff + sta success + + ; fall through to _close_file +_close_file + lda stream + bne _close_good + clc + rts +_close_good + sta kernel.args.file.close.stream + jsr kernel.File.Close + + jmp _event_loop + + +_start_program + .if false + lda #'!' + jsr putc + jsr put_cr + .endif + + + ; Run program + jsr _start_enter + bcc _exited_reinit + + ; Carry set, reset machine + stz $01 + lda #$DE + sta $D6A2 + lda #$AD + sta $D6A3 + lda #$80 + sta $D6A0 + stz $D6A0 +_spin bra _spin ; wait for reset + +_exited_reinit + ; Reinitialize essential DOS functionality. + jsr kernel.Display.Reset + jsr display.init + jsr display.cls + + ; Tell the event call where to dump events. + lda #event + sta kernel.args.events+1 + + clc + rts +_start_enter + jmp (header.entry) + + +_start_read + .if false + lda #'+' + jsr putc + lda remaining+1 + jsr display.print_hex + lda remaining + jsr display.print_hex + jsr put_cr + .endif + + ; Set read length, max 128 bytes at a time + lda remaining+1 + bne _limit_read + lda remaining + bpl _read_len_good +_limit_read + lda #128 +_read_len_good + sta kernel.args.file.read.buflen + + ; Set stream id and start read + lda stream + sta kernel.args.file.read.stream + + jsr kernel.File.Read + bcs _close_file + + jmp _event_loop + + + .send + .endn + diff --git a/dos/cmd_keys.asm b/dos/cmd_keys.asm index 142a4ef..d675e87 100755 --- a/dos/cmd_keys.asm +++ b/dos/cmd_keys.asm @@ -32,9 +32,9 @@ _loop _joy ldx #0 lda event.joystick.joy0 - jsr print_hex + jsr display.print_hex lda event.joystick.joy1 - jsr print_hex + jsr display.print_hex bra _loop _released @@ -60,27 +60,6 @@ _done clc rts -print_hex - pha - lsr a - lsr a - lsr a - lsr a - jsr _digit - pla - and #$0f - jsr _digit - rts -_digit - phy - tay - lda _digits,y - ply - sta $c000,x - inx - rts -_digits - .text "0123456789abcdef" .send .endn diff --git a/dos/cmd_write.asm b/dos/cmd_write.asm index 3c549ae..cca5f46 100755 --- a/dos/cmd_write.asm +++ b/dos/cmd_write.asm @@ -18,6 +18,7 @@ cmd bne _done ; Set the drive + lda #1 ; Token #1 jsr readline.parse_drive sta kernel.args.file.open.drive diff --git a/dos/display.asm b/dos/display.asm index cc8db7e..eabd3d7 100755 --- a/dos/display.asm +++ b/dos/display.asm @@ -13,7 +13,6 @@ display .namespace src .word ? dest .word ? len .byte ? -line_ptr .word ? cur_line .byte ? scroll .byte ? @@ -21,7 +20,6 @@ color .byte ? curcol .byte ? cursor .byte ? screen .word ? -str .word ? .send TEXT_LUT_FG = $d800 @@ -44,6 +42,8 @@ init rts + + set_cursor jsr cursor_off sta cursor @@ -73,7 +73,29 @@ update_cursor sty io_ctrl ply rts - + + +print_hex + pha + lsr a + lsr a + lsr a + lsr a + jsr _digit + pla + and #$0f + jsr _digit + rts +_digit + phy + tay + lda _digits,y + ply + jmp putc +_digits + .text "0123456789abcdef" + + putchar pha phy diff --git a/dos/dos.asm b/dos/dos.asm index bd182a8..888c911 100755 --- a/dos/dos.asm +++ b/dos/dos.asm @@ -43,7 +43,11 @@ mmu .fill 8 .cerror * > $00ff, "Out of dp space." .endv - .virtual $0200 ; Application memory + .virtual $0200 + .dsection kupdata ; Data transferable to Kernel User Programs + .endv + + .virtual $0300 ; Application memory .dsection pages ; Aligned segments .endv @@ -81,64 +85,13 @@ soft jmp cmd.start welcome - jsr hardware - jsr ukernel - jsr fat32 - rts + lda #>_msg + ldx #<_msg + jmp strings.puts_zero -hardware - phy - ldy #0 -_loop lda _msg,y - beq _done - jsr putc - iny - bra _loop -_done - ply - rts -_msg - .text "Foenix F256 by Stefany Allaire", $0a - .text "https://c256foenix.com/f256-jr",$0a - .text $0a, $00 - -ukernel - phy - ldy #0 -_loop lda _msg,y - beq _done - jsr putc - iny - bra _loop -_done - ply - rts -_msg - .text "TinyCore MicroKernel", $0a - .text "Copyright 2022 Jessie Oberreuter", $0a - .text "Gadget@HackwrenchLabs.com",$0a - .text "F256 Edition built ", DATE_STR, $0a - .text $0a, $00 - -fat32 - phy - ldy #0 -_loop lda _msg,y - beq _done - jsr putc - iny - bra _loop -_done - ply - rts -_msg - .text "Fat32 from https://github.com/commanderx16/x16-rom", $0a - .text "Copyright 2020 Frank van den Hoef and Michael Steil", $0a - .text $0a - .text "Simple DOS Shell, built ", DATE_STR, $0a - .text $0a - .byte $0 +_msg .text "Foenix F256 DOS Shell (", DATE_STR, ")", $0a, $0a, 0 + basic lda #<_basic sta kernel.args.buf+0 diff --git a/dos/reader.asm b/dos/reader.asm index f7e39c2..0036109 100755 --- a/dos/reader.asm +++ b/dos/reader.asm @@ -31,6 +31,7 @@ read_file stz stop ; Set the drive + lda #1 ; Token #1 jsr readline.parse_drive sta kernel.args.file.open.drive @@ -63,6 +64,8 @@ _loop beq _done cmp #kernel.event.file.NOT_FOUND beq _not_found + cmp #kernel.event.file.ERROR + beq _not_found jsr _dispatch bra _loop @@ -78,8 +81,6 @@ _dispatch beq _read cmp #kernel.event.file.DATA beq _data - cmp #kernel.event.file.ERROR - beq _eof cmp #kernel.event.file.EOF beq _eof cmp #kernel.event.key.PRESSED diff --git a/dos/readline.asm b/dos/readline.asm index 0090293..863c4f1 100755 --- a/dos/readline.asm +++ b/dos/readline.asm @@ -10,17 +10,18 @@ MAX_TOKENS = 8 line .word ? .send - .section pages -buf .fill 256 ; Only need 80, but now it's aligned. - .send - .section data cursor .byte ? length .byte ? tokens .fill MAX_TOKENS token_count .byte ? ; Token count .send - + + .section kupdata +buf .fill 128 ; Only need 80, must be page aligned +argv .fill (readline.MAX_TOKENS+1)*2 + .send + .section code read @@ -190,6 +191,36 @@ _done ply rts +populate_arguments: + ; Populate argv array + ldx #0 + ldy #0 +_copy_token + lda readline.tokens,y + sta argv,x + inx + lda #>readline.buf + sta argv,x + inx + iny + cpy readline.token_count + bne _copy_token + + ; null terminate argv array + stz argv,x + stz argv+1,x + + ; Set ext and extlen to argv and argc + lda #argv + sta kernel.args.ext+1 + lda readline.token_count + asl a + sta kernel.args.extlen + + rts + tokenize ldx #0 ; Token count ldy #0 ; Start of line @@ -267,6 +298,8 @@ _out rts parse_drive + ; IN: A = token# + tax ; Make sure we have an argument lda token_count @@ -274,7 +307,7 @@ parse_drive bcc _default ; Make sure it's at least 2 characters - lda #1 ; token 1 + txa jsr token_length cmp #2 bcc _default diff --git a/dos/strings.asm b/dos/strings.asm index 7782d75..3f5243d 100755 --- a/dos/strings.asm +++ b/dos/strings.asm @@ -27,15 +27,14 @@ puts_cr jsr puts jmp put_cr -puts +puts_zero + ; Input - XA string + phx phy - tay - lda Strings+0,y - sta strings.str+0 - lda Strings+1,y + stx strings.str+0 sta strings.str+1 - + ldy #0 _loop lda (strings.str),y @@ -44,6 +43,19 @@ _loop iny bra _loop _done + ply + plx + clc + rts + +puts + phy + + tay + ldx Strings+0,y + lda Strings+1,y + jsr puts_zero + ply clc rts