Merge branch 'FeralChild64-master'

This commit is contained in:
Roman committed 2021-02-28 21:05:38 +01:00
commit eebecb2b2c
118 files changed
+3226 -1101

No files matched your search

+3
View File
@@ -4,3 +4,6 @@
[submodule "3rdparty/zmac"]
path = 3rdparty/zmac
url = https://github.com/FeralChild64/zmac
[submodule "3rdparty/z80exer"]
path = 3rdparty/z80exer
url = https://github.com/FeralChild64/z80exer
Vendored Submodule
+1
Submodule 3rdparty/z80exer added at 8634cccdd3.
+19 -5
View File
@@ -62,8 +62,11 @@ SRCDIR_KERNAL = $(SRCDIR_COMMON) \
SRCDIR_DOS_M65 = $(SRCDIR_COMMON) \
src/dos_m65 \
# src/dos_m65/cmdrdos \
src/dos_m65/sdcard
src/dos_m65/assets \
src/dos_m65/dev_floppy \
src/dos_m65/dev_ramdisk \
src/dos_m65/dev_sdcard \
src/dos_m65/utils
SRCDIR_MON_M65 = $(SRCDIR_COMMON) \
src/mon_m65
@@ -107,6 +110,7 @@ DIR_ZMAC = 3rdparty/zmac/src
DIR_ZMAC_TMP = build/,tmp_zmac
HDR_ZMAC = $(filter-out $(wildcard $(DIR_ZMAC)/_*.h),$(wildcard $(DIR_ZMAC)/*.h))
SRC_ZMAC = $(DIR_ZMAC)/mio.c $(DIR_ZMAC)/doc.c $(DIR_ZMAC)/zi80dis.cpp
SRC_Z80TEST = 3rdparty/z80exer/cpm/zexdoc.src
GEN_ZMAC_C = $(DIR_ZMAC_TMP)/zmac.c
GEN_ZMAC_H = $(DIR_ZMAC_TMP)/doc.inl
@@ -209,6 +213,7 @@ TARGET_LIST_TST = $(TARGET_TST_B) $(TARGET_TST_K)
TARGET_LIST_U64 = $(TARGET_U64_B) $(TARGET_U64_K)
TARGET_LIST_U64CRT = $(TARGET_U64CRT_B) $(TARGET_U64CRT_K) $(TARGET_U64CRT_X)
TARGET_Z80TEST = ./build/cpm/Z80TEST.COM
TARGET_LIST = $(TARGET_CHR_ORF) \
$(TARGET_LIST_CUS) \
@@ -289,7 +294,7 @@ $(ROM_CBM_BASIC):
# Rules - tools
$(DIR_ACME) $(SRC_ACME) $(DIR_ZMAC) $(SRC_ZMAC):
$(DIR_ACME) $(SRC_ACME) $(DIR_ZMAC) $(SRC_ZMAC) $(SRC_Z80TEST):
@echo
@echo Fetching 3rd party source code...
@git submodule init
@@ -390,7 +395,7 @@ $(DIR_M65)/kernal.seg_C $(DIR_M65)/KERNAL_C_combined.vs $(DIR_M65)/KERNAL_C_comb
$(DIR_M65)/kernal.seg_1 $(DIR_M65)/KERNAL_1_combined.vs $(DIR_M65)/KERNAL_1_combined.sym: \
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_M65) $(GEN_STR_M65) $(DIR_M65)/KERNAL_0_combined.sym
$(DIR_M65)/dos.seg_1 $(DIR_M65)/DOS_1_combined.vs $(DIR_M65)/DOS_1_combined.sym: \
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_DOS_M65) $(CFG_M65)
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_DOS_M65) $(CFG_M65) $(DIR_M65)/KERNAL_0_combined.sym
$(DIR_M65)/mon.seg_1 $(DIR_M65)/MON_1_combined.vs $(DIR_M65)/MON_1_combined.sym: \
$(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_MON_M65) $(CFG_M65) $(DIR_M65)/KERNAL_0_combined.sym $(DIR_M65)/BASIC_1_combined.sym
$(DIR_M65)/zvm.seg_1 $(DIR_M65)/ZVM_1_combined.vs $(DIR_M65)/ZVM_1_combined.sym: \
@@ -881,8 +886,9 @@ testsimilarity: $(TOOL_SIMILARITY) $(DIR_GEN)/OUTx_x.BIN $(ROM_CBM_KERNAL) $(ROM
# Z80 part
#
.PHONY: cpm
cpm: $(TOOL_ASSEMBLER_Z80)
cpm: $(TOOL_ASSEMBLER_Z80) $(TARGET_Z80TEST)
$(DIR_ZMAC_TMP)/doc: $(SRC_ZMAC)
@mkdir -p $(DIR_ZMAC_TMP)
@@ -904,3 +910,11 @@ $(TOOL_ASSEMBLER_Z80): $(DIR_ZMAC) $(SRC_ZMAC) $(GEN_ZMAC_C) $(GEN_ZMAC_H) $(HDR
@echo Compiling tool $@ ...
@mkdir -p build/tools
@$(CC) -o $(TOOL_ASSEMBLER_Z80) $(SRC_ZMAC) $(GEN_ZMAC_C) -lm -w -I$(DIR_ZMAC) -I$(DIR_ZMAC_TMP)
$(TARGET_Z80TEST) : $(TOOL_ASSEMBLER_Z80) $(SRC_Z80TEST)
@echo
@echo Compiling Z80 CPU tester ...
@mkdir -p build/cpm
@rm -f $(TARGET_Z80TEST).CIM $(TARGET_Z80TEST)
@$(TOOL_ASSEMBLER_Z80) -o $(TARGET_Z80TEST).CIM $(SRC_Z80TEST)
@mv -f $(TARGET_Z80TEST).CIM $(TARGET_Z80TEST)
+6 -4
View File
@@ -101,6 +101,7 @@ The following ROM features are currently missing:
| :----------------: | :------: | :------------------------------------------------: |
| standard | DONE | |
| JiffyDOS | PARTIAL | LOAD needs improvement for better performance |
| ELoad v1 | NOT DONE | |
| DolphinDOS | DONE | |
| CIA burst mod | NOT DONE | |
| MEGA65 burst | NOT DONE | |
@@ -125,10 +126,11 @@ The following ROM features are currently missing:
<br />
| Driver | Status | Remarks |
| :----------------: | :------: | :-------------------------------------------------------------------------: |
| internal floppy | NOT DONE | try to reuse https://github.com/commanderx16/x16-rom/tree/master/dos |
| SD card access | NOT DONE | tryy to reuse https://github.com/commanderx16/x16-rom/tree/master/dos/fat32 |
| Driver | Status | Remarks |
| :----------------: | :------: | :------------------------------------------------: |
| SD card | PARTIAL | work-in-progress, can already load files |
| floppy drive | NOT DONE | |
| ram disk | NOT DONE | |
<br />
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+2
View File
@@ -186,6 +186,8 @@ Last, but not least - the `#TAKE-HIGH` is intended to be used for BASIC routines
### MEGA65 computer-based DOS
Both the internal DOS and all the IEC operations leave with CPU speed set to 1 MHz (in case of legacy compatibility mode) or 40 MHz (in case of native mode). Also the fast interrupts and badline emulation is set according to the mode.
TODO
### CPU-specific optimizations
+2 -5
View File
@@ -30,7 +30,6 @@
;; #CONFIG# IEC_DOLPHINDOS NO
;; #CONFIG# IEC_DOLPHINDOS_FAST NO
;; #CONFIG# IEC_JIFFYDOS NO ; fastloaders do not work on MEGA65 yet!
;; #CONFIG# IEC_JIFFYDOS_BLANK NO
;; #CONFIG# IEC_BURST_M65 NO ; please keep disabled for now
@@ -66,7 +65,7 @@
;; #CONFIG# KEYCMD_HELP "LIST"
;; #CONFIG# KEYCMD_F9 "REM F9"
;; #CONFIG# KEYCMD_F9 "@20$"
;; #CONFIG# KEYCMD_F10 "\5FL"
;; #CONFIG# KEYCMD_F11 "COLORSET 128"
;; #CONFIG# KEYCMD_F12 "\5FHF"
@@ -91,9 +90,7 @@
; --- Built-in DOS configuration
;; #CONFIG# CMDRDOS NO ; do not change, DOS is not implemented yet
;; #CONFIG# UNIT_SDCARD 0 ; do not change, DOS is not implemented yet
;; #CONFIG# UNIT_SDCARD 20 ; do not change, DOS is not implemented yet
;; #CONFIG# UNIT_FLOPPY 0 ; do not change, DOS is not implemented yet
;; #CONFIG# UNIT_RAMDISK 0 ; do not change, DOS is not implemented yet
+1 -12
View File
@@ -112,6 +112,7 @@
!ifdef CONFIG_MB_MEGA65 {
!ifdef CONFIG_IEC_BURST_CIA1 { !error "Do not use CONFIG_IEC_BURST_CIA1 options for MEGA65 motherboard, CONFIG_IEC_BURST_M65 instead" }
!ifdef CONFIG_IEC_BURST_CIA2 { !error "Do not use CONFIG_IEC_BURST_CIA2 options for MEGA65 motherboard, CONFIG_IEC_BURST_M65 instead" }
!ifdef IEC_JIFFYDOS_BLANK { !error "Do not use IEC_JIFFYDOS_BLANK option for MEGA65 motherboard, it is not needed" }
!ifndef CONFIG_DOS_WEDGE { !error "MEGA65 build requires CONFIG_DOS_WEDGE" }
}
!ifndef CONFIG_MB_MEGA65 {
@@ -247,12 +248,6 @@
!ifndef CONFIG_VIC_PALETTE { !error "CONFIG_VIC_PALETTE not specified" }
}
; Check that internal DOS configuration is correct
!ifdef CONFIG_CMDRDOS { !ifndef CONFIG_MB_M65 {
!error "CONFIG_CMDRDOS requires CONFIG_MB_M65"
} }
; Check that startup banner configuration is correct
@@ -424,12 +419,6 @@
; Handle non-LGPL3 code
!ifdef CONFIG_CMDRDOS { !set HAS_NOLGPL3_WARN = 1 }
; Determine if we need space-savings in BASIC code
!ifndef CONFIG_MB_M65 { !ifndef ROM_LAYOUT_CRT {
+6
View File
@@ -48,6 +48,7 @@
!addr SD_CTL = $D680
!addr SD_ADDR = $D681 ; 4 bytes
!addr SD_BUFCTL = $D689
!addr SD_ERRCODE = $D6DA
; SD card sector buffer, $FFFD6E00
@@ -72,6 +73,11 @@
!addr MISC_BOARDID = $D629 ; board identification byte
!addr MISC_EMU = $D710 ; to enable badlines and slow interrupts
; Hypervisor traps
!addr HTRAP00 = $D640
; SID offsets
!set __SID_R1_OFFSET = $00 ; right SID 1, $D400
+1 -1
View File
@@ -291,7 +291,7 @@
!set IEC_BURST = 3
}
!ifdef CONFIG_MB_M65 {
!set IEC_ROMDOS = 4
!set IEC_CBDOS = 4
}
+2
View File
@@ -50,6 +50,8 @@
;; #ALIAS# m65_shadow_BZP = KERNAL_0.m65_shadow_BZP
;; #ALIAS# proxy_M1_IO_end = KERNAL_0.proxy_M1_IO_end
;; #ALIAS# m65dos_unitnum = KERNAL_0.m65dos_unitnum
;
; Ultimate 64 specific parts
;
-15
View File
@@ -1,15 +0,0 @@
;; #LAYOUT# M65 BASIC_1 #TAKE
;; #LAYOUT# * * #IGNORE
!ifdef HAS_NOLGPL3_WARN {
str_nonlgpl3_warn:
!byte $0D, $0D, $0D, $0D
!pet "build contains non-lgpl3 code"
!byte $0D
!pet " *** do not distribute ***"
!byte $0D, $0D, $00
}
+36 -2
View File
@@ -106,12 +106,46 @@ print_sysinfo_video:
@5:
jsr print_packed_misc_str
; Print build featires information
; Print build features information
ldx #IDX__STR_SI_FEATURES
jmp print_packed_misc_str
jsr print_packed_misc_str
; Print SD CARD unit ID
lda #$00
jsr cmd_sysinfo_print_dev
ldx #IDX__STR_DOS_FD
jsr print_packed_misc_str
; Print floppy unit ID
lda #$01
jsr cmd_sysinfo_print_dev
; Print ram disk unit ID
ldx #IDX__STR_DOS_RD
jsr print_packed_misc_str
lda #$02
jsr cmd_sysinfo_print_dev
jmp print_return
cmd_sysinfo_print_dev:
jsr m65dos_unitnum
bcs @nounit
tax
lda #$00
jmp print_integer
@nounit:
lda #'-'
jmp JCHROUT
cmd_sysinfo_hw_ids:
+1
View File
@@ -46,3 +46,4 @@
;; #ALIAS# fetch_character_skip_spaces = BASIC_0.proxy_B1_fetch_character_skip_spaces
;; #ALIAS# fetch_uint8 = BASIC_0.proxy_B1_fetch_uint8
;; #ALIAS# shell_main_loop = BASIC_0.proxy_B1_shell_main_loop
;; #ALIAS# m65dos_unitnum = BASIC_0.proxy_B1_m65dos_unitnum
+6
View File
@@ -156,3 +156,9 @@ proxy_M1_print_kernal_error:
jsr do_error_print_only
jmp proxy_M1_IO_end
}
proxy_B1_m65dos_unitnum:
jsr map_NORMAL
jsr m65dos_unitnum
bra proxy_B1_end_2
+2 -11
View File
@@ -31,11 +31,11 @@ INITMSG_native:
; Native mode
ldx #48
ldx #44
ldy #0
jsr M65_SETWIN_XY
ldx #32
ldx #36
ldy #9
jsr M65_SETWIN_WH
@@ -64,18 +64,9 @@ INITMSG_native:
jsr initmsg_bytes_free
!ifdef HAS_NOLGPL3_WARN {
lda #<str_nonlgpl3_warn
ldy #>str_nonlgpl3_warn
jmp STROUT
} else {
ldx #$09
ldy #$00
jmp plot_set
}
INITMSG_main_banner:
-2
View File
@@ -115,5 +115,3 @@ initmsg_real:
}
}
!ifdef HAS_NOLGPL3_WARN { !error "HAS_NOLGPL3_WARN not implemented" }
+110 -18
View File
@@ -3,40 +3,132 @@
;
; NOTES:
; - DOS zeropage is mirrored at $8000
; - starting from $8000, 16KB RAM is available (starting from $10000 in C65 address space)
; - additional 16KB RAM is reserved for DOS too ($14000-$17FFF), and can be banked-in if needed
;
; Page 0
; Temporary storage locations
;
!addr MAGICSTR = $00 ; magic string; if not matching, DOS considered non-functional
!addr FS_HVSR_DIRENT = $1000
;
; Page start+0
;
!addr MAGICSTR = $8000 ; magic string; if not matching, DOS considered non-functional
; Register storage
!addr REG_A = $8005
!addr REG_X = $8006
!addr REG_Y = $8007
!addr REG_Z = $8008
; Reserved: $8009 - $800C
; General DOS configuration
!addr UNIT_SDCARD = $05
!addr UNIT_FLOPPY = $06
!addr UNIT_RAMDISK = $07
!addr UNIT_SDCARD = $800D ; unit number for device, 0 = none
!addr UNIT_FLOPPY = $800E ; as above
!addr UNIT_RAMDISK = $800F ; as above
; SD/SDHC card variables
; General DOS status
!addr CARD_INIT_DONE = $08 ; $80 - init done, $00 - init not done
!addr CARD_IS_SDHC = $09 ; $00 = SD, $80 = SDHC
!addr CARD_SIZE = $0A ; 4 bytes
!addr CARD_SECNUM = $0E ; 4 bytes - sector number
!addr IDX1_LISTENER = $8010 ; listener idx, >=$80 = none
!addr IDX2_LISTENER = $8011 ; listener idx * 2, >=$80 = none - for calling routines via vector table
!addr IDX1_TALKER = $8012 ; talker idx, >=$80 = none
!addr IDX2_TALKER = $8013 ; talker idx * 2, >=$80 = none - for calling routines via vector table
!addr CARD_TMP_STEP = $12 ; 4 bytes
!addr CARD_TMP_RETRIES = $16 ; 1 byte
; Helper subroutines to fetch data
!addr CARD_BUFPNT1 = $17 ; 4 bytes - pointer to hardware sector buffer XXX replace copy routines with DMAgic
!addr CARD_BUFPNT2 = $1B ; 4 bytes - as above, but points to the 2nd page of the hardware buffer
!addr code_LDA_nnnn_Y = $8014 ; - LDA nnnn, Y instruction
!addr par_LDA_nnnn_Y = $8015 ; - 2 bytes; address in buffer, ram disk
!addr code_RTS_04 = $8017 ; - RTS instruction
; Parameters for utilities/helkpers
!addr PAR_TRACK = $8018 ; track number for status/error
!addr PAR_SECTOR = $8019 ; sector number for status/error
!addr PAR_FSIZE_BYTES = $801A ; 4 bytes - file size in bytes
!addr PAR_FSIZE_BLOCKS = $801E ; 2 bytes - file size in blocks
!addr PAR_FTYPE = $8020 ; bits 0-5 - type, bits 6-7 - protected, closed
!addr PAR_FNAME = $8021 ; 16 bytes - filename, filled with $A0
!addr PAR_FPATTERN = $8031 ; 16 bytes - pattern to match, filled with $A0
; Various temporary data
!addr XX_DIR_PHASE = $8041 ; directory output phase, values deponds on device driver, but 0 = not reading
!addr SD_DIR_PHASE = $8041 ; - SD card
!addr FD_DIR_PHASE = $8042 ; - floppy
!addr RD_DIR_PHASE = $8043 ; - ram disk
; Free space: $8044-$8063
!addr SD_ACPTR_helper = $8052 ; subroutine in RAM to read a byte
!addr code_LDA_01 = $8052 ; - LDA instruction
!addr SD_ACPTR_PTR = $8053 ; - 2 bytes; address in buffer, SD card
!addr code_RTS_01 = $8055 ; - RTS instruction
!addr FD_ACPTR_helper = $8056 ; subroutine in RAM to read a byte
!addr code_LDA_02 = $8056 ; - LDA instruction
!addr FD_ACPTR_PTR = $8057 ; - 2 bytes; address in buffer, floppy
!addr code_RTS_02 = $8059 ; - RTS instruction
!addr RD_ACPTR_helper = $805A ; subroutine in RAM to read a byte
!addr code_LDA_03 = $805A ; - LDA instruction
!addr RD_ACPTR_PTR = $805B ; - 2 bytes; address in buffer, ram disk
!addr code_RTS_03 = $805D ; - RTS instruction
!addr XX_ACPTR_LEN = $805E ; 2 bytes - length of data left for ACPTR
!addr SD_ACPTR_LEN = $805E ; - SD card
!addr FD_ACPTR_LEN = $8060 ; - floppy
!addr RD_ACPTR_LEN = $8062 ; - ram disk
!addr XX_MODE = $8064 ; current mode (0 = none, 1 = receiving command/file name)
!addr SD_MODE = $8064 ; - SD card
!addr FD_MODE = $8065 ; - floppy
!addr RD_MODE = $8066 ; - ram disk
!addr XX_CHANNEL = $8067 ; current channel
!addr SD_CHANNEL = $8067 ; - SD card
!addr FD_CHANNEL = $8068 ; - floppy
!addr RD_CHANNEL = $8069 ; - ram disk
!addr XX_CMDFN_IDX = $806A ; index byte for storing file name/command
!addr SD_CMDFN_IDX = $806A ; - SD card
!addr FD_CMDFN_IDX = $806B ; - floppy
!addr RD_CMDFN_IDX = $806C ; - ram disk
!addr XX_STATUS_IDX = $806D ; index byte for reading status
!addr SD_STATUS_IDX = $806D ; - SD card
!addr FD_STATUS_IDX = $806E ; - floppy
!addr RD_STATUS_IDX = $806F ; - ram disk
!addr XX_STATUS_STR = $8070
!addr SD_STATUS_STR = $8070 ; status string for SD card, terminated by 0
!addr FD_STATUS_STR = $80A0 ; status string for floppy drive, terminated by 0
!addr RD_STATUS_STR = $80D0 ; status string for ram disk, terminated by 0
;
; High memory
; Further pages
;
!addr CARD_BUF = $8100 ; 512 bytes, up to $82FF - buffer for reading/writing data
!addr SD_CMDFN_BUF = $8100 ; buffer for command and/or file name, 128 bytes, SD card
!addr FD_CMDFN_BUF = $8180 ; buffer for command and/or file name, 128 bytes, floppy
!addr RD_CMDFN_BUF = $8200 ; buffer for command and/or file name, 128 bytes, ram disk
!addr XX_DIR_ENTRY = $8280 ; directory entry in BASIC format
!addr SD_DIR_ENTRY = $8280 ; - SD card
!addr FD_DIR_ENTRY = $82B0 ; - floppy
!addr RD_DIR_ENTRY = $82E0 ; - ram disk
!addr SD_MEMSHADOW = $8310 ; 256 byte buffer for preserving original memory content
!addr SD_FILEBUF = $8410 ; 512 byte buffer for file reading
!addr SD_DESC = $8610 ; current file descriptor
+11 -10
View File
@@ -2,13 +2,14 @@
; A vector table to integrate DOS with the MEGA65 Kernal
!word dos_INIT
!word dos_CHKUNIT
!word dos_SETUNIT
!word dos_ACPTR
!word dos_CIOUT
!word dos_LISTEN
!word dos_SECOND
!word dos_TALK
!word dos_TKSA
!word dos_UNTLK
!word dos_UNLSN
!word dos_UNITCHK
!word dos_UNITSET
!word dos_UNITNUM
!word msg_ACPTR
!word msg_CIOUT
!word msg_LISTEN
!word msg_SECOND
!word msg_TALK
!word msg_TKSA
!word msg_UNTLK
!word msg_UNLSN
File renamed without changes.
+62
View File
@@ -0,0 +1,62 @@
;
; Data used to generate directory in CBM BASIC format
;
dir_hdr: ; 32 bytes - header
!byte $01, $08 ; program location
!byte $01, $01 ; link to the next line - dummy, will be regenerated by BASIC
!byte $00, $00 ; line number 0
!byte $12, $22 ; reverse mode, quote
!pet " " ; space for disk/directory name
!byte $22, $20 ; quote, space
!pet "00 2a" ; default ID, disk format
!byte $00 ; end of the line
dir_hdr_sd: ; 32 bytes - header
!byte $01, $08 ; program location
!byte $01, $01 ; link to the next line - dummy, will be regenerated by BASIC
!byte $00, $00 ; line number 0
!byte $12, $22 ; reverse mode, quote
!pet "sd card " ; space for disk/directory name
!byte $22, $20 ; quote, space
!pet "fat32" ; filesystem
!byte $00 ; end of the line
dir_end: ; 19 bytes
!byte $01, $01 ; link to the next line - dummy, will be regenerated by BASIC
!byte $00, $00 ; line number 0 (blocks available)
!pet "blocks free."
!byte $00, $00, $00 ; end of the line, end of program marker
; File types / extensions
dir_types:
!pet "seq", $00 ; SEQ
!pet "prg", $00 ; PRG
!pet "usr", $00 ; USR
!pet "rel", $00 ; REL
!pet "dir", $00 ; directory
; File types below are not mandatory
!pet "tap", $00 ; tape image
!pet "d67", $00 ; CBM 2040 (DOS 1) - disk image
!pet "d64", $00 ; CBM 1541 / 2031 / 3040 / 4040 - disk image
!pet "d71", $00 ; CBM 1571 - disk image
!pet "d81", $00 ; CBM 1581 - disk image
!pet "d80", $00 ; CBM 8050 - disk image
!pet "d81", $00 ; CBM 8250 / 1001 - disk image
!pet "d90", $00 ; CBM D9060 / D9090 - hard disk image
!pet "d1m", $00 ; CMD FD 2000 / 4000 - disk image (DD)
!pet "d2m", $00 ; CMD FD 2000 / 4000 - disk image (HD)
!pet "d4m", $00 ; CMD FD 4000 - disk image (ED)
!pet "dhd", $00 ; CMD HD - hard disk image
!pet "rom", $00 ; rom image
!pet "m65", $00 ; MEGA65 utility
dir_types__end:
+184
View File
@@ -0,0 +1,184 @@
;
; DOS error codes and strings
;
; XXX get rid of unnecessary error messages
dos_sts_init_sdcard:
!pet "73,m65 dos sd card,00,00", 0
dos_sts_init_floppy:
!pet "73,m65 dos floppy,00,00", 0
dos_sts_init_ramdisk:
!pet "73,m65 dos ram disk,00,00", 0
; List compiled from various manuals (CBM 1571, CBM 1581, CMD FD4000, MSD Super Disk, IDE64)
dos_sts_00: ; not an error
!pet " ok", 0
dos_sts_01: ; not an error
!pet "files scratched", 0
dos_sts_02: ; not an error
!pet "partition selected", 0
dos_sts_20: ; header not found
dos_sts_21: ; no data addres mark
dos_sts_22: ; block not found
dos_sts_23: ; data error
dos_sts_27: ; header error
!pet "read error", 0
dos_sts_25:
!pet "write error", 0
dos_sts_26:
!pet "write protect on", 0
dos_sts_29:
!pet "disk changed", 0
dos_sts_30: ; invalid characters in command
dos_sts_31: ; unrecognized command
dos_sts_32: ; command too long
dos_sts_33: ; illegal file name
dos_sts_34: ; missing file name
!pet "syntax error", 0
dos_sts_39:
!pet "file not found", 0
dos_sts_49: ; disk formatted, but format not supported
!pet "invalid format", 0
dos_sts_50:
!pet "record not present", 0
dos_sts_51:
!pet "overflow in record", 0
dos_sts_52:
!pet "file too large", 0
dos_sts_60:
!pet "write file open", 0
dos_sts_61:
!pet "file not open", 0
dos_sts_62:
!pet "file not found", 0
dos_sts_63:
!pet "file exists", 0
dos_sts_64:
!pet "file type mismatch", 0
dos_sts_65:
!pet "no block", 0
dos_sts_66:
!pet "illegal track and sector", 0
dos_sts_67:
!pet "illegal system t or s", 0
dos_sts_70:
!pet "no channel", 0
dos_sts_71:
!pet "directory error", 0
dos_sts_72:
!pet "partition full", 0
dos_sts_73:
!pet "dos mismatch", 0
dos_sts_74:
!pet "drive not ready", 0
dos_sts_75:
!pet "format error", 0
dos_sts_76:
!pet "controller error", 0
dos_sts_77:
!pet "selected partition illegal", 0
dos_sts_78:
!pet "system error", 0
dos_sts_79: ; SD2IEC compatible
!pet "image invalid", 0
dos_sts_XX: ; Open ROMs specific - unspecified error
!pet "internal error", 0
dos_sts_tab_lo:
!byte <dos_sts_00, <dos_sts_01, <dos_sts_02, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX
!byte <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX
!byte <dos_sts_20, <dos_sts_21, <dos_sts_22, <dos_sts_23, <dos_sts_XX, <dos_sts_25, <dos_sts_26, <dos_sts_27, <dos_sts_XX, <dos_sts_29
!byte <dos_sts_30, <dos_sts_31, <dos_sts_32, <dos_sts_33, <dos_sts_34, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_39
!byte <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_49
!byte <dos_sts_50, <dos_sts_51, <dos_sts_52, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX, <dos_sts_XX
!byte <dos_sts_60, <dos_sts_61, <dos_sts_62, <dos_sts_63, <dos_sts_64, <dos_sts_65, <dos_sts_66, <dos_sts_67, <dos_sts_XX, <dos_sts_XX
!byte <dos_sts_70, <dos_sts_71, <dos_sts_72, <dos_sts_73, <dos_sts_74, <dos_sts_75, <dos_sts_76, <dos_sts_77, <dos_sts_78, <dos_sts_79
!byte <dos_sts_XX
dos_sts_tab_hi:
!byte >dos_sts_00, >dos_sts_01, >dos_sts_02, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX
!byte >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX
!byte >dos_sts_20, >dos_sts_21, >dos_sts_22, >dos_sts_23, >dos_sts_XX, >dos_sts_25, >dos_sts_26, >dos_sts_27, >dos_sts_XX, >dos_sts_29
!byte >dos_sts_30, >dos_sts_31, >dos_sts_32, >dos_sts_33, >dos_sts_34, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_39
!byte >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_49
!byte >dos_sts_50, >dos_sts_51, >dos_sts_52, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX, >dos_sts_XX
!byte >dos_sts_60, >dos_sts_61, >dos_sts_62, >dos_sts_63, >dos_sts_64, >dos_sts_65, >dos_sts_66, >dos_sts_67, >dos_sts_XX, >dos_sts_XX
!byte >dos_sts_70, >dos_sts_71, >dos_sts_72, >dos_sts_73, >dos_sts_74, >dos_sts_75, >dos_sts_76, >dos_sts_77, >dos_sts_78, >dos_sts_79
!byte >dos_sts_XX
-4
View File
@@ -1,4 +0,0 @@
!ifndef HAS_NOLGPL3_WARN {
!error "No LGPL3 incompatible warning issued"
}
+11
View File
@@ -0,0 +1,11 @@
;
; Close currently opened file
;
dev_fd_cmd_CLOSE:
; XXX provide implementation
jmp dos_EXIT_SEC
+17
View File
@@ -0,0 +1,17 @@
;
; Open file for reading
;
dev_fd_cmd_OPEN:
; XXX provide implementation
jmp dos_EXIT_SEC
dev_fd_cmd_OPEN_EOI:
; XXX provide implementation
jmp dos_EXIT_CLC
+12
View File
@@ -0,0 +1,12 @@
;
; Read more data into the buffer
;
dev_fd_cmd_READ:
; XXX provide implementation
sec ; mark EOI
rts
+28
View File
@@ -0,0 +1,28 @@
;
; Initializes DOS part of floppy controller
;
dev_fd_init:
; Copy status string
ldx #$00
stx FD_STATUS_IDX
stx FD_CMDFN_IDX
stx FD_MODE
stx FD_ACPTR_LEN+0
stx FD_ACPTR_LEN+1
stx FD_ACPTR_PTR+0
stx FD_ACPTR_PTR+1
dex
@1:
inx
lda dos_sts_init_floppy,x
sta FD_STATUS_STR,x
bne @1
; End of initialization
rts
@@ -0,0 +1,11 @@
;
; Close currently opened file
;
dev_rd_cmd_CLOSE:
; XXX provide implementation
jmp dos_EXIT_SEC
+17
View File
@@ -0,0 +1,17 @@
;
; Open file for reading
;
dev_rd_cmd_OPEN:
; XXX provide implementation
jmp dos_EXIT_SEC
dev_rd_cmd_OPEN_EOI:
; XXX provide implementation
jmp dos_EXIT_CLC
+12
View File
@@ -0,0 +1,12 @@
;
; Read more data into the buffer
;
dev_rd_cmd_READ:
; XXX provide implementation
sec ; mark EOI
rts
+28
View File
@@ -0,0 +1,28 @@
;
; Initializes DOS part of ram disk
;
dev_rd_init:
; Copy status string
ldx #$00
stx RD_STATUS_IDX
stx RD_CMDFN_IDX
stx RD_MODE
stx RD_ACPTR_LEN+0
stx RD_ACPTR_LEN+1
stx RD_ACPTR_PTR+0
stx RD_ACPTR_PTR+1
dex
@1:
inx
lda dos_sts_init_ramdisk,x
sta RD_STATUS_STR,x
bne @1
; End of initialization
rts
+11
View File
@@ -0,0 +1,11 @@
;
; Close currently opened file
;
dev_sd_cmd_CLOSE:
; XXX provide implementation
jmp dos_EXIT_CLC
+73
View File
@@ -0,0 +1,73 @@
;
; Open file for reading
;
dev_sd_cmd_OPEN:
lda #$01 ; mode: receive command or file name
sta SD_MODE
jmp dos_EXIT_CLC
dev_sd_cmd_OPEN_EOI:
; XXX this dispatcher is temporary
; Erase filter pattern XXX this should be moved to common part
ldy #$0F
lda #$A0
@lp1:
sta PAR_FPATTERN, y
dey
bpl @lp1
; XXX add support for second card
lda SD_CMDFN_BUF
cmp #'$'
beq dev_sd_cmd_OPEN_dir
; FALLTROUGH
dev_sd_cmd_OPEN_file:
; Copy the filter from command XXX this should be moved to common part and deduplicated with directory opening
ldy #$00
@lp1:
lda SD_CMDFN_BUF, y
cmp #$A0
beq @lp1_end
sta PAR_FPATTERN, y
iny
cpy #$10
bne @lp1
@lp1_end:
jmp fs_hvsr_read_file_open
dev_sd_cmd_OPEN_dir:
lda #$02 ; mode: read directory
sta SD_MODE
; Copy the filter from command XXX this should be moved to common part and deduplicated with file opening
ldy #$00
@lp1:
lda SD_CMDFN_BUF+1, y
cmp #$A0
beq @lp1_end
sta PAR_FPATTERN, y
iny
cpy #$10
bne @lp1
@lp1_end:
jmp fs_hvsr_read_dir_open
+20
View File
@@ -0,0 +1,20 @@
;
; Read more data into the buffer
;
dev_sd_cmd_READ:
lda SD_MODE
cmp #$03
+beq fs_hvsr_read_file
lda SD_DIR_PHASE
cmp #$01
+beq fs_hvsr_read_dir
cmp #$02
+beq fs_hvsr_read_dir_blocksfree
sec ; mark EOI
rts
+39
View File
@@ -0,0 +1,39 @@
;
; Initializes DOS part of SD card
;
dev_sd_init:
; Copy initial status string
ldx #$00
stx SD_STATUS_IDX
stx SD_CMDFN_IDX
stx SD_MODE
stx SD_ACPTR_LEN+0
stx SD_ACPTR_LEN+1
stx SD_ACPTR_PTR+0
stx SD_ACPTR_PTR+1
stx SD_DIR_PHASE
dex
@1:
inx
lda dos_sts_init_sdcard,x
sta SD_STATUS_STR,x
bne @1
; Close all the files in the hypervisor, go to root directory
lda #$22 ; dos_closeall
sta HTRAP00
+nop
lda #$3C ; dos_cdrootdir
sta HTRAP00
+nop
; End of initialization
rts
+250
View File
@@ -0,0 +1,250 @@
;
; Hypervisor virtual filesystem - reading directory
;
fs_hvsr_read_dir_open:
; Open the directory
lda #$12 ; dos_opendir
sta HTRAP00
+nop
; XXX handle read errors
sta SD_DESC ; store directory descriptor XXX invent better name
; Reset status to OK
lda #$00
sta PAR_TRACK
sta PAR_SECTOR
jsr util_status_SD
; Provide pointer to the header
lda #$20
sta SD_ACPTR_LEN+0
lda #$00
sta SD_ACPTR_LEN+1
lda #<dir_hdr_sd
sta SD_ACPTR_PTR+0
lda #>dir_hdr_sd
sta SD_ACPTR_PTR+1
; Set directory phase to 'file name'
lda #$01
sta SD_DIR_PHASE
; End
jmp dos_EXIT_CLC
fs_hvsr_read_dir:
; Read dirent structure into $1000, process it, restore the memory content.
; Starting at $1000 VIC sees chargen, so this should be a safe place
jsr fs_hvsr_direntmem_prepare
jsr fs_hvsr_util_nextdirentry
jsr fs_hvsr_direntmem_restore ; processor status is preserved
; If nothing to read, output 'blocks free'
+bcs fs_hvsr_read_dir_blocksfree
; Check if file name matches the filter
jsr util_dir_filter
bne fs_hvsr_read_dir ; if does not match, try the next entry
; Otherwise, convert the file length from bytes to blocks to display
jsr util_dir_filesize_bytes
; Prepare output entry, starting from XX_DIR_ENTRY + initial offset
ldx #$00 ; offset for SD card unit
lda #$01 ; link to the next line - dummy, will be regenerated by BASIC
sta XX_DIR_ENTRY, x
inx
sta XX_DIR_ENTRY, x
inx
lda PAR_FSIZE_BLOCKS+0 ; store number of blocks
sta XX_DIR_ENTRY, x
inx
lda PAR_FSIZE_BLOCKS+1
sta XX_DIR_ENTRY, x
inx
lda #' ' ; indent file name
@lp1:
dey
bmi @lp1_done
sta XX_DIR_ENTRY, x
inx
bra @lp1
@lp1_done:
lda #$22 ; opening quote
sta XX_DIR_ENTRY, x
inx
ldy #$FF ; put file name
@lp2:
iny
lda PAR_FNAME, y
cmp #$A0
beq @lp2_done
cpy #$10
beq @lp2_done
sta XX_DIR_ENTRY, x
inx
bra @lp2
@lp2_done:
lda #$22 ; closing quote
sta XX_DIR_ENTRY, x
inx
ldy #$10 ; put spaces for indentation
@lp3:
dey
lda PAR_FNAME, y
cmp #$A0
bne @lp3_done
lda #' '
sta XX_DIR_ENTRY, x
inx
bra @lp3
@lp3_done:
lda PAR_FTYPE ; put 'damaged' mark if needed
bmi @closed
lda #'*'
+skip_2_bytes_trash_nvz
@closed:
lda #' '
sta XX_DIR_ENTRY, x
inx
lda PAR_FTYPE ; put file type
and #$3F
dec
asl
asl
tay
@lp4:
lda dir_types, y
beq @lp4_done
sta XX_DIR_ENTRY, x
inx
iny
bra @lp4
@lp4_done:
lda PAR_FTYPE ; read-only mark (if needed)
and #$40
beq @skipro
lda #'<'
sta XX_DIR_ENTRY, x
inx
@skipro:
lda #$00 ; put end of the line
sta XX_DIR_ENTRY, x
inx
stx SD_ACPTR_LEN+0
sta SD_ACPTR_LEN+1
lda #<(XX_DIR_ENTRY)
sta SD_ACPTR_PTR+0
lda #>(XX_DIR_ENTRY)
sta SD_ACPTR_PTR+1
clc
rts
fs_hvsr_read_dir_blocksfree:
; Set pointer to 'BLOCKS FREE.' line
; XXX determine free space
lda #$13
sta SD_ACPTR_LEN+0
lda #$00
sta SD_ACPTR_LEN+1
lda #<dir_end
sta SD_ACPTR_PTR+0
lda #>dir_end
sta SD_ACPTR_PTR+1
; Mark end of directory
lda #$00
sta SD_DIR_PHASE
; Close the directory within the hypervisor XXX maybe move it to close routine
ldx SD_DESC
lda #$16 ; dos_closedir
sta HTRAP00
+nop
clc
rts
;
; Helper routines
;
fs_hvsr_direntmem_prepare:
ldx #$00
@1:
ldy $1000, x
sty SD_MEMSHADOW, x
inx
bne @1
rts
fs_hvsr_direntmem_restore:
php
ldx #$00
@1:
ldy SD_MEMSHADOW, x
sty $1000, x
inx
bne @1
bne @1
plp
rts
+151
View File
@@ -0,0 +1,151 @@
;
; Hypervisor virtual filesystem - opening the file
;
fs_hvsr_read_file_open:
; Open the directory
lda #$12 ; dos_opendir
sta HTRAP00
+nop
; XXX handle read errors
sta SD_DESC ; store directory descriptor XXX invent better name
; Reset status to OK
lda #$00
sta PAR_TRACK
sta PAR_SECTOR
jsr util_status_SD
; XXX deduplicate part above with opening directory
; Read dirent structures into $1000, find the first matching file
; Starting at $1000 VIC sees chargen, so this should be a safe place
jsr fs_hvsr_direntmem_prepare
@lp_find:
jsr fs_hvsr_util_nextdirentry ; fetch the next file name
+bcs fs_hvsr_file_not_found
; Only accept files of type 'PRG', properly closed
lda PAR_FTYPE
and #%10111111
cmp #$82
bne @lp_find
; Check if file name matches the filter
jsr util_dir_filter
bne @lp_find ; if does not match, try the next entry
; Found the file - load it
jsr fs_hvsr_direntmem_restore ; restore $1000 memory content
lda #$18 ; dos_openfile
sta HTRAP00
+nop
; XXX check error code
; Read the first 512-byte chunk
lda #$03 ; mode: read file
sta SD_MODE
jsr fs_hvsr_read_file
jmp dos_EXIT
fs_hvsr_read_file:
; Read chunk of data to SD card buffer
ldx SD_DESC
lda #$1A ; dos_readfile
sta HTRAP00
+nop
; XXX check error code
; Store number of bytes read
stx SD_ACPTR_LEN+0
sty SD_ACPTR_LEN+1
; Check if any data was read
tya
ora SD_ACPTR_LEN+0
bne @copy
lda #$20 ; dos_closefile
sta HTRAP00
+nop
lda #$00
sec
rts
@copy:
; Set pointer to new data
lda #<SD_FILEBUF
sta SD_ACPTR_PTR+0
lda #>SD_FILEBUF
sta SD_ACPTR_PTR+1
; Copy data to SD_FILEBUF
lda #%10000000 ; select SD card buffer
tsb SD_BUFCTL
lda #$02
sta DMA_ADDRBANK ; $D702
lda #$00
sta DMA_ADDRMB ; $D704
lda #>(@dmalist-$4000)
sta DMA_ADDRMSB ; $D701
lda #<(@dmalist-$4000)
sta DMA_ETRIG ; $D705
clc
rts
@dmalist:
!byte $0A ; use F018A list format (it is shorter by 1 byte)
!byte $80, $FF ; src. address is $FFxxxxx
!byte $81, $00 ; dst. address is $00xxxxx
!byte $00 ; end of options
!byte $00 ; operation: COPY
!word $0200 ; data size if 512 bytes
!byte $00, $6E, $0D ; src. addr is $xxD6E00
!byte <(SD_FILEBUF - $8000)
!byte >(SD_FILEBUF - $8000)
!byte $01 ; dst. addr is $xx1xxxx (internal buffer)
fs_hvsr_file_not_found:
jsr fs_hvsr_direntmem_restore ; restore $1000 memory content
ldx SD_DESC
lda #$16 ; dos_closedir
sta HTRAP00
+nop
lda #39 ; file not found error
jsr util_status_SD
lda #K_ERR_FILE_NOT_FOUND
jmp dos_EXIT_SEC_A
@@ -0,0 +1,243 @@
;
; Hypervisor virtual filesystem - helper routine to get the next directory entry
;
; Fills-in: PAR_FNAME, PAR_FTYPE, PAR_FSIZE_BYTES
; NOTE: overrides page pointed by FS_HVSR_DIRENT!
; XXX work-in-progress, this should be used within directory reading code
fs_hvsr_util_nextdirentry:
; Clear the page which will be used
ldx #$00
txa
@lpclear:
sta FS_HVSR_DIRENT, x
inx
bne @lpclear
; Ask the hypervisor to read the next dirent structure
ldx SD_DESC ; directory descriptor XXX rename to FS_HVSR_DESC
ldy #>FS_HVSR_DIRENT ; target page number
lda #$14 ; dos_readdir
sta HTRAP00
+nop
+bcc @fail
; Reading entry succeeded, try to decode it. Important dirent fileds:
; - $00-$3F - file name
; - $40 - file name length
; - $52-$55 - file length
; - $56-$57 - file type ($10 = dir, $20 = regular) and attributes ($01 for read-only)
;
; Preprocess/validate the filename
;
ldx FS_HVSR_DIRENT+$40 ; file name length
beq fs_hvsr_util_nextdirentry ; do not even try for empty file name
cpx #20
bcs fs_hvsr_util_nextdirentry ; if longer than 16 characters + dot + extension - also skip this one
dex
@lpname:
lda FS_HVSR_DIRENT,x
cmp #$22
beq fs_hvsr_util_nextdirentry ; quotation mark is illegal
cmp #$2A
beq fs_hvsr_util_nextdirentry ; asterisk is illegal, it is used for filtering
cmp #$3F
beq fs_hvsr_util_nextdirentry ; the question mark - in the MS-DOS world it is illegal
cmp #$20
bcc fs_hvsr_util_nextdirentry ; control characters are not allowed
cmp #$5B
bcc @lpname_next ; up to PETSCII 'Z' is OK
cmp #$61
bcc fs_hvsr_util_nextdirentry ; some characters are not allowed
cmp #$7E
bne @lpname_1
lda #$A6 ; replace tilde / pi with something more sane
bra @lpname_store_next
@lpname_1:
cmp #$7B
bcs fs_hvsr_util_nextdirentry ; PETSCII-art and control characters are illegal
clc
sbc #$20 ; make everything the same case
@lpname_store_next:
sta FS_HVSR_DIRENT,x ; use this when file name has to be adapted
@lpname_next:
dex
bpl @lpname
;
; Determine type (file/directory)
;
lda FS_HVSR_DIRENT+$56
tax
and #$FE
beq @entity_file ; workaround for older hypervisors
and #$20
bne @entity_file ; branch on file
txa
and #$10
beq fs_hvsr_util_nextdirentry ; this type is unknown
@entity_dir:
; Once again validate the name length, with more precise information
lda FS_HVSR_DIRENT+$40
cmp #$11
bcs fs_hvsr_util_nextdirentry ; skip entry if file name longer than 16 characters
; Set the type to directory
lda #$05
bra @detect_attributes
@entity_file:
; Once again validate the name length, with more precise information
lda FS_HVSR_DIRENT+$40
sec
sbc #$04 ; strip 4 bytes - for dot and extension
bmi fs_hvsr_util_nextdirentry ; if name too short, try next entry
beq fs_hvsr_util_nextdirentry ; if name too short, try next entry
sta FS_HVSR_DIRENT+$40 ; store corrected file name length
tax
; Make sure there is a dot marking the start of a 3-byte extension
lda FS_HVSR_DIRENT, x
cmp #$2E
+bne fs_hvsr_util_nextdirentry
;
; Detect file type by extension
;
inx
ldy #$00
@lpext:
lda FS_HVSR_DIRENT+0, x
cmp dir_types+0, y
bne @lpext_next
lda FS_HVSR_DIRENT+1, x
cmp dir_types+1, y
bne @lpext_next
lda FS_HVSR_DIRENT+2, x
cmp dir_types+2, y
beq @lpext_found
@lpext_next:
iny
iny
iny
iny
cpy #(dir_types__end - dir_types)
bcc @lpext
jmp fs_hvsr_util_nextdirentry ; file extension not detected
@lpext_found:
cpy #$10
+beq fs_hvsr_util_nextdirentry ; file extension 'DIR' does not mean this is a directory
tya
clc
ror
clc
ror
inc
cmp #$06 ; mark some file types (not SEQ/PRG/USR/REL/DIR) as read-only
bcc @detect_attributes
ora #$40
@detect_attributes:
ora #$80 ; mark the file as closed, FAT32 does not have a 'not closed' attribute
sta PAR_FTYPE
lda FS_HVSR_DIRENT+$56 ; also apply read-only attribute from FAT32
and #$01
beq @copy_size
lda PAR_FTYPE
ora #$40
sta PAR_FTYPE
@copy_size:
; Copy the file size
ldx #$03
@lpsize:
lda FS_HVSR_DIRENT+$52,x ; copy file size in byytes
sta PAR_FSIZE_BYTES,x
dex
bpl @lpsize
@copy_name:
; Last, but not least - copy file name
lda #$A0 ; fill-in empty bytes with $A0, to simulate CBM file system
ldx #$0F
@lpname_cpy:
cpx FS_HVSR_DIRENT+$40
bcs @lpname_fill
lda FS_HVSR_DIRENT, x
@lpname_fill:
sta PAR_FNAME,x
dex
bpl @lpname_cpy
; All done
clc
rts
@fail:
; Reading next entry failed, this is the end
; XXX check error code
sec
rts
-63
View File
@@ -1,63 +0,0 @@
;
; Unit number handling. For detailed description see 'm65dos_bridge.s' file
;
dos_CHKUNIT:
; Check for magic string
pha
phx
ldx #$04
@1:
lda MAGICSTR, x
cmp dos_magicstr, x
bne dos_CHKUNIT_mem_fail
dex
bpl @1
plx
pla
; Check for unit
cmp UNIT_SDCARD
beq dos_CHKUNIT_sdcard
cmp UNIT_FLOPPY
beq dos_CHKUNIT_floppy
cmp UNIT_RAMDISK
beq dos_CHKUNIT_ramdisk
sec
rts
dos_CHKUNIT_sdcard:
lda #$00
+skip_2_bytes_trash_nvz
; FALLTROUGH
dos_CHKUNIT_floppy:
lda #$01
+skip_2_bytes_trash_nvz
; FALLTROUGH
dos_CHKUNIT_ramdisk:
lda #$02
clc
rts
dos_CHKUNIT_mem_fail:
plx
pla
sec
rts
+58
View File
@@ -0,0 +1,58 @@
; Helper routines for entering/exiting the context
dos_ENTER: ; enter DOS context
php
jsr m65_speed_tape_cbdos
plp
sta REG_A
stx REG_X
sty REG_Y
stz REG_Z
rts
dos_EXIT_SEC: ; exit DOS context with Carry set
sec
bra dos_EXIT
dos_EXIT_CLC: ; exit DOS context with Carry clear
clc
; FALLTROUGH
dos_EXIT:
lda REG_A
bra dos_EXIT_A
dos_EXIT_SEC_A: ; exit DOS context with Carry set, return .A
sec
bra dos_EXIT_A
dos_EXIT_CLC_A: ; exit DOS context with Carry clear, return .A
clc
; FALLTROUGH
dos_EXIT_A:
ldz REG_Z
ldy REG_Y
ldx REG_X
php
jsr m65_speed_restore
plp
rts
+14
View File
@@ -0,0 +1,14 @@
;; #IMPORT# KERNAL_0 = KERNAL_0_combined.sym
;
; Definitions for calling MEGA65 segment KERNAL_0 routines from DOS_1
;
;; #ALIAS# MONITOR = KERNAL_0.MONITOR
;; #ALIAS# kernalstatus_EOI = KERNAL_0.kernalstatus_EOI
;; #ALIAS# kernalstatus_DEVICE_NOT_FOUND = KERNAL_0.kernalstatus_DEVICE_NOT_FOUND
;; #ALIAS# m65_speed_tape_cbdos = KERNAL_0.m65_speed_tape_cbdos
;; #ALIAS# m65_speed_restore = KERNAL_0.m65_speed_restore
+48 -6
View File
@@ -3,11 +3,22 @@
; Initializes DOS. For detailed description see 'm65dos_bridge.s' file
;
!set CONFIG_UNIT_FLOPPY = 0 ; XXX floppy not supported yet
!set CONFIG_UNIT_RAMDISK = 0 ; XXX RAM disk not supported yet
dos_INIT:
; Safer version of 'dos_ENTER' - does not affect speed related registers
sta REG_A
stx REG_X
sty REG_Y
stz REG_Z
; Set the magic string 'CBDOS'
phx
ldx #$04
@1:
lda dos_magicstr, x
@@ -15,8 +26,6 @@ dos_INIT:
dex
bpl @1
plx
; Set default device numbers
lda #CONFIG_UNIT_SDCARD
@@ -26,9 +35,42 @@ dos_INIT:
lda #CONFIG_UNIT_RAMDISK
sta UNIT_RAMDISK
; Mark SD card as not initialized
; Clear listener / talker
lda #$00
sta CARD_INIT_DONE
lda #$FF
sta IDX1_LISTENER
sta IDX2_LISTENER
sta IDX1_TALKER
sta IDX2_TALKER
; Initialize device handlers
jsr dev_sd_init
jsr dev_fd_init
jsr dev_rd_init
; Initialize helper code in RAM
lda #$AD ; LDA opcode, absolute
sta code_LDA_01
sta code_LDA_02
sta code_LDA_03
lda #$B9 ; LDA nnnn, y opcode
sta code_LDA_nnnn_Y
lda #$60 ; RTS opcode
sta code_RTS_01
sta code_RTS_02
sta code_RTS_03
sta code_RTS_04
; Safer version of 'dos_EXIT' - does not affect speed related registers
clc
ldz REG_Z
ldy REG_Y
ldx REG_X
lda REG_A
rts
+50
View File
@@ -0,0 +1,50 @@
;
; Check if DOS memory is not overwritten
;
dos_MEMCHK:
pha
phx
; Check for magic string
ldx #$04
@1:
lda MAGICSTR, x
cmp dos_magicstr, x
bne @fail
dex
bpl @1
; Check if helper code is undamaged
lda #$AD
cmp code_LDA_01
bne @fail
cmp code_LDA_02
bne @fail
cmp code_LDA_03
bne @fail
lda #$60
cmp code_RTS_01
bne @fail
cmp code_RTS_02
bne @fail
cmp code_RTS_03
bne @fail
plx
pla
clc
rts
@fail:
plx
pla
sec
rts
-42
View File
@@ -1,42 +0,0 @@
;
; Unit number handling. For detailed description see 'm65dos_bridge.s' file
;
dos_SETUNIT:
; XXX check if .X is valid
cmp #$00
beq dos_SETUNIT_sdcard
cmp #$01
beq dos_SETUNIT_floppy
cmp #$02
beq dos_SETUNIT_ramdisk
sec
rts
dos_SETUNIT_sdcard:
stx UNIT_SDCARD
+skip_2_bytes_trash_nvz
; FALLTROUGH
dos_SETUNIT_floppy:
stx UNIT_FLOPPY
+skip_2_bytes_trash_nvz
; FALLTROUGH
dos_SETUNIT_ramdisk:
stx UNIT_RAMDISK
; FALLTROUGH
clc
rts
+50
View File
@@ -0,0 +1,50 @@
;
; Unit number handling. For detailed description see 'm65dos_bridge.s' file
;
dos_UNITCHK:
; Before the start make sure memory content is not damaged
jsr dos_MEMCHK
bcc @ok
rts
@ok:
jsr dos_ENTER
; Check for unit
cmp UNIT_SDCARD
beq dos_UNITCHK_sdcard
cmp UNIT_FLOPPY
beq dos_UNITCHK_floppy
cmp UNIT_RAMDISK
beq dos_UNITCHK_ramdisk
; FALLTROUGH
dos_UNITCHK_fail:
jmp dos_EXIT_SEC
dos_UNITCHK_sdcard:
lda #$00
+skip_2_bytes_trash_nvz
; FALLTROUGH
dos_UNITCHK_floppy:
lda #$01
+skip_2_bytes_trash_nvz
; FALLTROUGH
dos_UNITCHK_ramdisk:
lda #$02
jmp dos_EXIT_CLC_A
+56
View File
@@ -0,0 +1,56 @@
;
; Unit number handling. For detailed description see 'm65dos_bridge.s' file
;
dos_UNITNUM:
; Before the start make sure memory content is not damaged
jsr dos_MEMCHK
bcc @ok
lda #$00 ; failure
rts
@ok:
jsr dos_ENTER
; Check what kind of device was requested
cmp #$00
beq dos_UNITNUM_sdcard
cmp #$01
beq dos_UNITNUM_floppy
cmp #$02
beq dos_UNITNUM_ramdisk
; FALLTROUGH
dos_UNITNUM_fail:
lda #$00
jmp dos_EXIT_SEC_A
dos_UNITNUM_sdcard:
lda UNIT_SDCARD
bra dos_UNITNUM_common
dos_UNITNUM_floppy:
lda UNIT_FLOPPY
bra dos_UNITNUM_common
dos_UNITNUM_ramdisk:
lda UNIT_RAMDISK
; FALLTROUGH
dos_UNITNUM_common:
cmp #$00
beq dos_UNITNUM_fail
jmp dos_EXIT_CLC_A
+49
View File
@@ -0,0 +1,49 @@
;
; Unit number handling. For detailed description see 'm65dos_bridge.s' file
;
dos_UNITSET:
; Before the start make sure memory content is not damaged
jsr dos_MEMCHK
bcc @ok
rts
@ok:
jsr dos_ENTER
; XXX do not allow illegal device numbers... above 30 or below 8 ?
; Check what kind of device was requested
cmp #$00
beq dos_UNITSET_sdcard
; XXX devices below are not implemented yet
; cmp #$01
; beq dos_UNITSET_floppy
; cmp #$02
; beq dos_UNITSET_ramdisk
jmp dos_EXIT_SEC
dos_UNITSET_sdcard:
stx UNIT_SDCARD
+skip_2_bytes_trash_nvz
; FALLTROUGH
dos_UNITSET_floppy:
stx UNIT_FLOPPY
+skip_2_bytes_trash_nvz
; FALLTROUGH
dos_UNITSET_ramdisk:
stx UNIT_RAMDISK
jmp dos_EXIT_CLC
+18
View File
@@ -0,0 +1,18 @@
;
; Vector tables to device-specific routines
;
dos_cmd_OPEN_vectab:
!word dev_sd_cmd_OPEN
!word dev_fd_cmd_OPEN
!word dev_rd_cmd_OPEN
dos_cmd_CLOSE_vectab:
!word dev_sd_cmd_CLOSE
!word dev_fd_cmd_CLOSE
!word dev_rd_cmd_CLOSE
+158
View File
@@ -0,0 +1,158 @@
;
; Implementation of ACPTR command. For detailed description see 'm65dos_bridge.s' file.
;
msg_ACPTR:
jsr dos_ENTER
; Check if there is a talker active
ldx IDX1_TALKER
bmi msg_ACPTR_fail_no_talker
; Check if active channel is status one
lda XX_CHANNEL, X
cmp #$0F
beq msg_ACPTR_status
; XXX add support for read contexts (multiple channels)
; Not a status channel - check if we have something to read out
ldx IDX2_TALKER
lda XX_ACPTR_LEN+0,x
ora XX_ACPTR_LEN+1,x
beq msg_ACPTR_fail_no_data
; Read a byte of data from the buffer
jmp (msg_ACPTR_read_vectab, X)
msg_ACPTR_read_SD:
; Read and return one byte
jsr SD_ACPTR_helper
sta TBTCNT
sta REG_A
; Increment pointer, decrement length
inc SD_ACPTR_PTR+0
bne @1
inc SD_ACPTR_PTR+1
@1:
dec SD_ACPTR_LEN+0
lda SD_ACPTR_LEN+0
cmp #$FF
bne @2
dec SD_ACPTR_LEN+1
@2:
; If new length is 0, try to read next block of data
ora SD_ACPTR_LEN+1
bne @3
jsr dev_sd_cmd_READ
bcc @3
jsr kernalstatus_EOI
@3:
jmp dos_EXIT_CLC
msg_ACPTR_read_FD:
; XXX provide implementation
msg_ACPTR_read_RD:
; XXX provide implementation
msg_ACPTR_fail_no_data:
; XXX What should be the reaction when trying to read and no data is present?
sta TBTCNT
sta REG_A
bra msg_ACPTR_EOI
msg_ACPTR_status:
ldx IDX2_TALKER
jmp (msg_ACPTR_status_vectab, X)
msg_ACPTR_status_SD: ; get next byte of status - SD card
ldx SD_STATUS_IDX
inc SD_STATUS_IDX
lda SD_STATUS_STR,x
bra msg_ACPTR_status_got
msg_ACPTR_status_FD: ; get next byte of status - floppy
ldx FD_STATUS_IDX
inc FD_STATUS_IDX
lda FD_STATUS_STR,x
bra msg_ACPTR_status_got
msg_ACPTR_status_RD: ; get next byte of status - ram disk
ldx RD_STATUS_IDX
inc RD_STATUS_IDX
lda RD_STATUS_STR,x
; FALLTROUGH
msg_ACPTR_status_got:
sta TBTCNT ; byte return
beq msg_ACPTR_reset_status
jmp dos_EXIT_CLC_A
msg_ACPTR_fail_no_talker:
; XXX set error code
jmp dos_EXIT_SEC
msg_ACPTR_reset_status:
ldx IDX2_TALKER
lda #$00
sta PAR_TRACK
sta PAR_SECTOR
jsr (msg_ACPTR_set_status_vectab, x)
; FALLTROUGH
msg_ACPTR_EOI:
jsr kernalstatus_EOI
jmp dos_EXIT_CLC
; Vector tables for jumps
msg_ACPTR_status_vectab:
!word msg_ACPTR_status_SD
!word msg_ACPTR_status_FD
!word msg_ACPTR_status_RD
msg_ACPTR_read_vectab:
!word msg_ACPTR_read_SD
!word msg_ACPTR_read_FD
!word msg_ACPTR_read_RD
msg_ACPTR_set_status_vectab:
!word util_status_SD
!word util_status_FD
!word util_status_RD
+92
View File
@@ -0,0 +1,92 @@
;
; Implementation of ACPTR command. For detailed description see 'm65dos_bridge.s' file.
;
msg_CIOUT:
jsr dos_ENTER
php
; Check operation mode
ldx IDX1_LISTENER
bmi msg_CIOUT_fail
lda XX_MODE, x
cmp #$01
bne @1
; Receiving command or file name
ldx IDX2_LISTENER
lda REG_A
jmp (msg_CIOUT_cmdfn_vectab, X)
@1:
; XXX handle cases of transferring data
plp
jmp dos_EXIT_SEC
msg_CIOUT_fail:
; XXX should we set status?
lda #K_ERR_DEVICE_NOT_FOUND
jmp dos_EXIT_SEC_A
; Receiving command/file name
msg_CIOUT_cmdfn_SD: ; get next byte of status - SD card
ldx SD_CMDFN_IDX
sta SD_CMDFN_BUF,x
inx
bpl @1
ldx #$7F
@1:
stx SD_CMDFN_IDX
lda #$A0
sta SD_CMDFN_BUF,x
plp
+bcs dev_sd_cmd_OPEN_EOI ; if EOI - execute command
jmp dos_EXIT_CLC
msg_CIOUT_cmdfn_FD: ; get next byte of status - floppy
ldx FD_CMDFN_IDX
sta FD_CMDFN_BUF,x
inx
bpl @1
ldx #$7F
@1:
stx FD_CMDFN_IDX
lda #$A0
sta FD_CMDFN_BUF,x
plp
+bcs dev_fd_cmd_OPEN_EOI ; if EOI - execute command
jmp dos_EXIT_CLC
msg_CIOUT_cmdfn_RD: ; get next byte of status - ram disk
ldx RD_CMDFN_IDX
sta RD_CMDFN_BUF,x
inx
bpl @1
ldx #$7F
@1:
stx RD_CMDFN_IDX
lda #$A0
sta RD_CMDFN_BUF,x
plp
+bcs dev_rd_cmd_OPEN_EOI ; if EOI - execute command
jmp dos_EXIT_CLC
msg_CIOUT_cmdfn_vectab:
!word msg_CIOUT_cmdfn_SD
!word msg_CIOUT_cmdfn_FD
!word msg_CIOUT_cmdfn_RD
+54
View File
@@ -0,0 +1,54 @@
;
; Implementation of LISTEN commands.
; For detailed description see 'm65dos_bridge.s' file.
;
msg_LISTEN:
jsr dos_ENTER
and #$1F
beq msg_LISTEN_fail ; branch if device 0 (used to denote lack of device)
cmp UNIT_SDCARD
bne @1
; LISTEN on SD card
lda #$00
bra msg_LISTEN_success
@1:
cmp UNIT_FLOPPY
bne @2
; LISTEN on floppy
lda #$01
bra msg_LISTEN_success
@2:
cmp UNIT_RAMDISK
bne msg_LISTEN_fail
; LISTEN on ram disk
lda #$02
; FALLTROUGH
msg_LISTEN_success:
sta IDX1_LISTENER
asl
sta IDX2_LISTENER
; XXX should we reset XX_CMDFN_IDX ?
jmp dos_EXIT_CLC
msg_LISTEN_fail:
lda #K_ERR_DEVICE_NOT_FOUND
jmp dos_EXIT_SEC_A
+49
View File
@@ -0,0 +1,49 @@
;
; Implementation of SECOND command.
; For detailed description see 'm65dos_bridge.s' file.
;
msg_SECOND:
jsr dos_ENTER
; First store the channel
tay
and #$0F ; support channels 0-15, like 1541 drive
ldx IDX1_LISTENER
bmi msg_SECOND_done ; do nothing if no listener
sta XX_CHANNEL, x ; store channel
; Determine command type
tya
and #$F0
cmp #$F0
beq msg_SECOND_OPEN
cmp #$E0
beq msg_SECOND_CLOSE
; XXX provide implementation
; FALLTROUGH
msg_SECOND_done:
jmp dos_EXIT_CLC
msg_SECOND_OPEN:
lda #$00
sta XX_CMDFN_IDX, x ; reset the index to the command/filename
ldx IDX2_LISTENER
jmp (dos_cmd_OPEN_vectab, x)
msg_SECOND_CLOSE:
ldx IDX2_LISTENER
jmp (dos_cmd_CLOSE_vectab, x)
+52
View File
@@ -0,0 +1,52 @@
;
; Implementation of TALK commands.
; For detailed description see 'm65dos_bridge.s' file.
;
msg_TALK:
jsr dos_ENTER
and #$1F
beq msg_TALK_fail ; branch if device 0 (used to denote lack of device)
cmp UNIT_SDCARD
bne @1
; TALK on SD card
lda #$00
bra msg_TALK_success
@1:
cmp UNIT_FLOPPY
bne @2
; TALK on floppy
lda #$01
bra msg_TALK_success
@2:
cmp UNIT_RAMDISK
bne msg_TALK_fail
; TALK on ram disk
lda #$02
; FALLTROUGH
msg_TALK_success:
sta IDX1_TALKER
asl
sta IDX2_TALKER
jmp dos_EXIT_CLC
msg_TALK_fail:
lda #K_ERR_DEVICE_NOT_FOUND
jmp dos_EXIT_SEC_A
+22
View File
@@ -0,0 +1,22 @@
;
; Implementation of TKSA commands.
; For detailed description see 'm65dos_bridge.s' file.
;
msg_TKSA:
jsr dos_ENTER
and #$0F ; support channels 0-15, like 1541 drive
ldx IDX1_TALKER
bmi msg_TKSA_done ; do nothing if no taalker
sta XX_CHANNEL, x ; store channel
; FALLTROUGH
msg_TKSA_done:
jmp dos_EXIT_CLC
+25
View File
@@ -0,0 +1,25 @@
;
; Implementation of UNLSN/UNTLK messages.
; For detailed description see 'm65dos_bridge.s' file.
;
msg_UNLSN:
jsr dos_ENTER
lda #$FF
sta IDX1_LISTENER
sta IDX2_LISTENER
jmp dos_EXIT_CLC
msg_UNTLK:
jsr dos_ENTER
sta IDX1_TALKER
sta IDX2_TALKER
jmp dos_EXIT_CLC
-93
View File
@@ -1,93 +0,0 @@
;
; Various helper routines for SD card support
;
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
;
; Sets read/write address
;
; Input: CARD_SECNUM, CARD_IS_SDHC
; Output: Carry set = error
; Preserves: .X, .Y, .Z
;
sdcard_set_addr:
bit CARD_IS_SDHC
bpl sdcard_set_addr_sdsc
sdcard_set_addr_sdhc:
lda CARD_SECNUM+0
sta SD_ADDR+0
lda CARD_SECNUM+1
sta SD_ADDR+1
lda CARD_SECNUM+2
sta SD_ADDR+2
lda CARD_SECNUM+3
sta SD_ADDR+3
; FALLTROUGH
sdcard_set_addr_done:
clc
rts
sdcard_set_addr_sdsc:
; Multiply sector number by 512
lda #$00
sta SD_ADDR+0
clc
lda CARD_SECNUM+0
rol
sta SD_ADDR+1
lda CARD_SECNUM+1
rol
sta SD_ADDR+2
lda CARD_SECNUM+2
rol
sta SD_ADDR+3
bcs sdcard_helper_fail ; branch if sector number too large for SD card
lda CARD_SECNUM+3
beq sdcard_set_addr_done ; do not branch if sector number too large for SD card
; FALLTROUGH
sdcard_helper_fail:
sec
rts
;
; Wait till card is ready
;
; Input: none
; Output: Carry set = error
; Preserves: .Y, .Z
sdcard_wait_ready:
; XXX if card does not get ready, try to reset it
lda SD_CTL
; Sometimes we see this result, i.e., sdcard.vhdl thinks it is done,
; but sdcardio.vhdl thinks not. This means a read error.
cmp #$01
beq sdcard_helper_fail
tax
and #$40
bne sdcard_helper_fail
txa
and #$03
bne sdcard_wait_ready
clc
rts
-243
View File
@@ -1,243 +0,0 @@
;
; Initialize memory card, determine it's type and size
;
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
; XXX finish the routine
sdcard_init:
; Initialize most important variables
lda #$00
sta CARD_IS_SDHC
lda #SD_SECBUF_0
sta CARD_BUFPNT1+0
sta CARD_BUFPNT2+0
lda #SD_SECBUF_1
sta CARD_BUFPNT1+1
inc
sta CARD_BUFPNT2+1
lda #SD_SECBUF_2
sta CARD_BUFPNT1+2
sta CARD_BUFPNT2+2
lda #SD_SECBUF_3
sta CARD_BUFPNT1+3
sta CARD_BUFPNT2+3
; Reset the card
jsr sdcard_reset
; Try to read first sector to see if card is operable
lda #$00
sta SD_ADDR+0
sta SD_ADDR+1
sta SD_ADDR+2
sta SD_ADDR+3
jsr sdcard_init_read
bcs sdcard_init_getsize_fail ; if failure, mark card as not operable and quit
; Work out if this is SD or SDHC card - SD cards can't read at non-sector aligned addresses
lda #$02
sta SD_ADDR+0
lda #$00
sta SD_ADDR+1
sta SD_ADDR+2
sta SD_ADDR+3
jsr sdcard_init_read
lda SD_CTL
beq sdcard_init_sdsc
; FALLTROUGH
sdcard_init_sdhc:
lda #$80
sta CARD_IS_SDHC
bra sdcard_init_getsize
sdcard_init_sdsc:
lda #$00
sta CARD_IS_SDHC
lda #CARD_CMD_SDHC_OFF ; $40 - use byte addressing
sta SD_CTL
; FALLTROUGH
sdcard_init_getsize:
; Work out size of SD card in a safe way
; (binary search of sector numbers is NOT safe for some reason.
; It frequently reports bigger than the size of the card)
; step (and first sector) = 16*2048
sta CARD_TMP_STEP+0
sta CARD_SECNUM+0
sta CARD_TMP_STEP+2
sta CARD_SECNUM+2
sta CARD_TMP_STEP+3
sta CARD_SECNUM+3
lda #$08
sta CARD_TMP_STEP+1
sta CARD_SECNUM+1
; FALLTROUGH
sdcard_init_getsize_read:
; Try to read sector
jsr sdcard_readsector
bcc sdcard_init_getsize_next ; XXX original code checks PEEK(sd_ctl)&0x63;...
; Failed to read - restore card state and sector number
jsr sdcard_reset
sec
lda CARD_SECNUM+0
sbc CARD_TMP_STEP+0
sta CARD_SECNUM+0
lda CARD_SECNUM+1
sbc CARD_TMP_STEP+1
sta CARD_SECNUM+1
lda CARD_SECNUM+2
sbc CARD_TMP_STEP+2
sta CARD_SECNUM+2
lda CARD_SECNUM+3
sbc CARD_TMP_STEP+3
sta CARD_SECNUM+3
; Divide step by 2, skip bytes which are always 0
clc
; ror CARD_TMP_STEP+3
; ror CARD_TMP_STEP+2
ror CARD_TMP_STEP+1
ror CARD_TMP_STEP+0
; FALLTROUGH
sdcard_init_getsize_next:
; Increment sector number by step
clc
lda CARD_SECNUM+0
adc CARD_TMP_STEP+0
sta CARD_SECNUM+0
lda CARD_SECNUM+1
adc CARD_TMP_STEP+1
sta CARD_SECNUM+1
lda CARD_SECNUM+2
adc CARD_TMP_STEP+2
sta CARD_SECNUM+2
lda CARD_SECNUM+3
adc CARD_TMP_STEP+3
sta CARD_SECNUM+3
; If sector number is 0 - report failure
lda CARD_SECNUM+0
ora CARD_SECNUM+1
ora CARD_SECNUM+2
ora CARD_SECNUM+3
beq sdcard_init_getsize_fail
; If step is 0 - this is the end, we know maximum size
lda CARD_TMP_STEP+0
ora CARD_TMP_STEP+1
ora CARD_TMP_STEP+2
ora CARD_TMP_STEP+3
beq sdcard_init_getsize_done
; Check sector number, should be below $10:$00:$00:$00
lda CARD_SECNUM+3
and #$F0
bne sdcard_init_getsize_read
; It is not - report maximum size
lda #$FF
sta CARD_SECNUM+0
sta CARD_SECNUM+1
sta CARD_SECNUM+2
lda #$0F
sta CARD_SECNUM+3
; FALLTROUGH
sdcard_init_getsize_done:
; Return sector number as maximum readable sector
lda CARD_SECNUM+0
sta CARD_SIZE+0
lda CARD_SECNUM+1
sta CARD_SIZE+1
lda CARD_SECNUM+2
sta CARD_SIZE+2
lda CARD_SECNUM+3
sta CARD_SIZE+3
clc
rts
sdcard_init_getsize_fail:
; XXX mark card as inoperable
sec
rts
;
; Helper routines
;
sdcard_init_read:
; Trigger read
lda #CARD_CMD_READ ; $02
sta SD_CTL
; Wait for result
ldx #90
@1:
jsr sdcard_wait_16000_usec
lda SD_CTL
and #$03
beq @2
dex
bne @1
; Read failed
sec
rts
@2:
;; Success
clc
rts
-97
View File
@@ -1,97 +0,0 @@
;
; Reads the sector from the SD card
;
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
; XXX provide documentation
sdcard_readsector:
; XXX check if card initialized and operable
; Set read address
jsr sdcard_set_addr
bcs sdcard_readsector_fail
; FALLTROUGH
sdcard_readsector_read:
; Set number of retries
lda #$0A
sta CARD_TMP_RETRIES
; FALLTROUGH
sdcard_readsector_try_loop:
; Wait till card is ready
jsr sdcard_wait_ready
bcs sdcard_readsector_fail
; Read command
lda #CARD_CMD_READ ; $02
sta SD_CTL
; Wait for command completion
jsr sdcard_wait_ready
bcs sdcard_readsector_fail
lda SD_CTL
and #$67
bne sdcard_readsector_copy_data
jsr sdcard_reset
dec CARD_TMP_RETRIES
bne sdcard_readsector_try_loop
; FALLTROUGH
sdcard_readsector_fail:
sec
rts
;
; Helper routines
;
sdcard_readsector_copy_data:
; XXX use DMAgic for this
phz
phx
ldx #$00
ldz #$00
@1:
lda [CARD_BUFPNT],z
sta CARD_BUF,x
inc CARD_BUFPNT+1
lda [CARD_BUFPNT],z
sta CARD_BUF+$100,x
dec CARD_BUFPNT+1
inz
inx
bne @1
; Restore registers and quit
plx
plz
clc
rts
-32
View File
@@ -1,32 +0,0 @@
;
; Resets the SD card
;
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
sdcard_reset:
ldx #CARD_CMD_SDHC_OFF ; $40
stx SD_CTL
ldy #CARD_CMD_RESET ; $00
sty SD_CTL
ldy #CARD_CMD_END_RESET ; $01
sty SD_CTL
; Wait till SD card resets
@1:
lda SD_CTL
and #$03
bne @1
; For SDHC card set appropriate mode
bit CARD_IS_SDHC
bpl @2
ldx #CARD_CMD_SDHC_ON ; $41
stx SD_CTL
@2:
rts
-26
View File
@@ -1,26 +0,0 @@
sdcard_wait_16000_usec:
; Uses VIC-II raster register; wait time is not exactly precise, but should be
; a good approximation
phx
pha
ldx #$FF
; XXX wait below is same as in KKERNAL, wait_x_lines - consider importing and reusing
lda VIC_RASTER
@1:
cmp VIC_RASTER
beq @1
lda VIC_RASTER
dex
bne @1
pla
plx
rts
-175
View File
@@ -1,175 +0,0 @@
;
; Writes the sector to the SD card
;
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
; XXX finish, provide documentation
sdcard_writesector:
; XXX check if card initialized and operable
lda SD_CTL
and #$03
bne sdcard_writesector ; XXX add a timer here
; End reset XXX is this needed? should this be done for sector reading too?
lda #CARD_CMD_END_RESET ; $01
sta SD_CTL
; Set write address
jsr sdcard_set_addr
bcs sdcard_writesector_fail
; FALLTROUGH
sdcard_writesector_write:
; Set number of retries
lda #$0A
sta CARD_TMP_RETRIES
; FALLTROUGH
sdcard_writesector_try_loop:
jsr sdcard_writesector_copy_data
; Wait till card is ready
jsr sdcard_wait_ready
bcs sdcard_writesector_fail
; Write command
lda #CARD_CMD_WRITE ; $03
sta SD_CTL
; Wait for command completion
jsr sdcard_wait_ready
bcs sdcard_writesector_fail
; Check result
lda SD_CTL
and #$67
bne sdcard_writesector_verify
; Write failed - retry
jsr sdcard_reset
dec CARD_TMP_RETRIES
bne sdcard_writesector_try_loop
; FALLTROUGH
sdcard_writesector_fail:
sec
rts
sdcard_writesector_verify:
; There is a bug in the SD controller; you have to read between writes,
; or it gets really upset
@1:
lda SD_CTL
and #$03
bne @1
lda #CARD_CMD_READ ; $02
sta SD_CTL
@2:
lda SD_CTL
and #$03
beq @2
@3: ; XXX deduplicate this ppart
lda SD_CTL
and #$03
bne @3
; FALLTROUGH
sdcard_writesector_verify_loop:
; Compare buffers
phx
phz
ldx #$00
ldz #$00
lda [CARD_BUFPNT1],z
cmp CARD_BUF, x
bne sdcard_writesector_verify_fail
lda [CARD_BUFPNT2],z
cmp CARD_BUF+$100, x
bne sdcard_writesector_verify_fail
inz
inx
bne sdcard_writesector_verify_loop
; FALLTROUGH
sdcard_writesector_verify_success:
plz
plx
clc
rts
sdcard_writesector_verify_fail:
plz
plx
sec
rts
;
; Helper routines
;
sdcard_writesector_copy_data:
; XXX use DMAgic for this
phz
phx
ldx #$00
ldz #$00
@1:
lda CARD_BUF,x
sta [CARD_BUFPNT1],z
lda CARD_BUF+$100,x
sta [CARD_BUFPNT2],z
inz
inx
bne @1
; Restore registers and quit
plx
plz
clc
rts
-22
View File
@@ -1,22 +0,0 @@
; Dummy implementations - XXX to be replaced with real ones
dos_ACPTR:
+nop
dos_CIOUT:
+nop
dos_LISTEN:
+nop
dos_SECOND:
+nop
dos_TALK:
+nop
dos_TKSA:
+nop
dos_UNTLK:
+nop
dos_UNLSN:
+nop
sec
rts
+182
View File
@@ -0,0 +1,182 @@
; Adapt the file size for displaying in a directory list
util_dir_filesize_bytes: ; preserves .X
; Convert file size in bytes (32-bit value) to blocks, afterwards
; continue processing in 'util_dir_filesize_blocks'
; Start from handling some large values
lda PAR_FSIZE_BYTES+3
+bne util_dir_filesize_max ; file over 16MB size
lda PAR_FSIZE_BYTES+2
inc
+beq util_dir_filesize_max ; file over 8MB size
; Set initial size as 0 blocks
lda #$00
sta PAR_FSIZE_BLOCKS+0
sta PAR_FSIZE_BLOCKS+1
; Calculate number of blocks
ldy #$03
@lp:
lda PAR_FSIZE_BYTES+2
cmp util_dir_cmptab_hi,y
bcc @lp_next
bne @lp_adc_sbc
lda PAR_FSIZE_BYTES+1
cmp util_dir_cmptab_mi,y
bcc @lp_next
bne @lp_adc_sbc
lda PAR_FSIZE_BYTES+0
cmp util_dir_cmptab_lo,y
bcc @lp_next
@lp_adc_sbc:
clc
lda PAR_FSIZE_BLOCKS+0
adc util_dir_addtab_lo,y
sta PAR_FSIZE_BLOCKS+0
lda PAR_FSIZE_BLOCKS+1
adc util_dir_addtab_hi,y
sta PAR_FSIZE_BLOCKS+1
sec
lda PAR_FSIZE_BYTES+0
sbc util_dir_cmptab_lo, y
sta PAR_FSIZE_BYTES+0
lda PAR_FSIZE_BYTES+1
sbc util_dir_cmptab_mi, y
sta PAR_FSIZE_BYTES+1
lda PAR_FSIZE_BYTES+2
sbc util_dir_cmptab_hi, y
sta PAR_FSIZE_BYTES+2
bra @lp
@lp_next:
dey
bpl @lp
; Correct for bytes not filling in the whole block
lda PAR_FSIZE_BYTES+0
beq util_dir_filesize_blocks
inc PAR_FSIZE_BLOCKS+0
bne util_dir_filesize_blocks
inc PAR_FSIZE_BLOCKS+1
; FALLTROUGH
util_dir_filesize_blocks: ; preserves .X
; Take file size in blocks (16-bit value), clip to max 9999,
; return in .Y the amount of spaces needed for indentation
lda PAR_FSIZE_BLOCKS+1
cmp #>9999
beq @cmp_9999_p2
bcs util_dir_filesize_max
bcc @size_ok
@cmp_9999_p2:
lda PAR_FSIZE_BLOCKS+0
cmp #<9999
bcs util_dir_filesize_max
@size_ok:
lda PAR_FSIZE_BLOCKS+1
beq @size_123
@size_34: ; file size is 256 or above (3 or 4 digits)
cmp #>1000
beq @cmp_1000_p2
bcs util_dir_filesize_4
bra util_dir_filesize_3
@cmp_1000_p2:
lda PAR_FSIZE_BLOCKS+0
cmp #<1000
bcs util_dir_filesize_4
bra util_dir_filesize_3
@size_123: ; file size is 255 or below (1, 2, or 3 digits)
lda PAR_FSIZE_BLOCKS+0
cmp #10
bcs util_dir_filesize_23
; FALLTROUGH
util_dir_filesize_1: ; file size needs 1 digit
ldy #$03
rts
util_dir_filesize_23: ; file size needs 2 or 3 digits, size in .A
cmp #100
bcs util_dir_filesize_3
; FALLTROUGH
util_dir_filesize_2: ; file size needs 2 digits
ldy #$02
rts
util_dir_filesize_3: ; file size needs 3 digits
ldy #$01
rts
util_dir_filesize_max:
lda #<9999
sta PAR_FSIZE_BLOCKS+0
lda #>9999
sta PAR_FSIZE_BLOCKS+1
; FALLTROUGH
util_dir_filesize_4: ; file size needs 4 digits
ldy #$00
rts
; Tables for calculating blocks from bytes
util_dir_addtab_hi:
!byte $00, $00 ; 2 next bytes same as in 'lo' table
util_dir_addtab_lo:
!byte $01, $10, $00, $00
util_dir_cmptab_hi:
!byte ^(254), ^(254 * 16), ^(254 * 16 * 16), ^(254 * 16 * 16 * 16), ^(254 * 16 * 16 * 16 * 16)
util_dir_cmptab_mi:
!byte >(254), >(254 * 16), >(254 * 16 * 16), >(254 * 16 * 16 * 16), >(254 * 16 * 16 * 16 * 16)
util_dir_cmptab_lo:
!byte <(254), <(254 * 16), <(254 * 16 * 16), <(254 * 16 * 16 * 16), <(254 * 16 * 16 * 16 * 16)
+28
View File
@@ -0,0 +1,28 @@
; Check if file name matches the filter (if so - Zero flag set)
util_dir_filter:
lda PAR_FPATTERN
cmp #$A0
beq @done ; branch if no filter
ldy #$00
@lp1:
lda PAR_FPATTERN, y
cmp #'*'
beq @done ; branch on wildcard
cmp PAR_FNAME, y
bne @done ; branch if does not match
iny
cpy #$10
bne @lp1 ; next iteration if maximum length not reached
@done:
rts
+125
View File
@@ -0,0 +1,125 @@
; Set current status or error
; XXX add code for handling the LEDs
; .A = status to set
util_status_SD:
ldx #$00
stx SD_STATUS_IDX ; set first byte of status to read
ldx #$00 ; offset to status buffer
bra util_status_common
util_status_FD:
ldx #$00
stx FD_STATUS_IDX ; set first byte of status to read
ldx #$20 ; offset to status buffer
bra util_status_common
util_status_RD:
ldx #$00
stx RD_STATUS_IDX ; set first byte of status to read
ldx #$40 ; offset to status buffer
; FALLLTROUGH
util_status_common:
; Store the error number
taz
jsr util_status_store_number
jsr util_status_store_comma
; Store the status / error string
tza ; prepare helper routine
tay
lda dos_sts_tab_lo, y
sta par_LDA_nnnn_Y+0
lda dos_sts_tab_hi, y
sta par_LDA_nnnn_Y+1
ldy #$00 ; copy the string
@lp:
jsr code_LDA_nnnn_Y
beq @lp_end
sta XX_STATUS_STR, x
iny
inx
bra @lp
@lp_end:
; Store track and sector
jsr util_status_store_comma
lda PAR_TRACK
jsr util_status_store_number
jsr util_status_store_comma
lda PAR_SECTOR
jsr util_status_store_number
; Mark end of status and quit
lda #$00
sta XX_STATUS_STR, x
rts
util_status_store_comma:
ldy #','
sty XX_STATUS_STR, x
inx
rts
util_status_store_number:
; Check if number to store is 200 or above
cmp #200
bcc @store_00_199
ldy #'2'
sty XX_STATUS_STR, x
inx
sec
sbc #200
bra @store_00_99
@store_00_199: ; number to store is within 00-199 range
cmp #100
bcc @store_00_99
ldy #'1'
sty XX_STATUS_STR, x
inx
sec
sbc #100
@store_00_99: ; number to store is within 00-99 range - separate digits
ldy #'0'
@lp:
cmp #10
bcc @store_finalize
iny
sec
sbc #10
bra @lp
@store_finalize: ; first digit to store in .Y, second in .A (need no add '0')
sty XX_STATUS_STR, x
inx
clc
adc #'0'
sta XX_STATUS_STR, x
inx
rts
@@ -1,45 +0,0 @@
;; #LAYOUT# M65 KERNAL_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Checks if system is in MEGA65 native mode; if so, switches CPU speed to fast/slow - for IEC routines;
; Alters only status bits, all remaining registers preserved
;
!ifdef CONFIG_IEC {
m65_iec_slow:
jsr M65_MODEGET
bcs m65_iec_fast_slow_done
; Switch CPU speed
pha
lda VIC_CTRLB
and #%10111111
bra m65_iec_fast_slow_common
m65_iec_fast:
jsr M65_MODEGET
bcs m65_iec_fast_slow_done
pha
lda VIC_CTRLB
ora #%01000000
; FALLTROUGH
m65_iec_fast_slow_common:
sta VIC_CTRLB
pla
; FALLTROUGH
m65_iec_fast_slow_done:
rts
}
+3
View File
@@ -40,6 +40,9 @@
;; #ALIAS# viciv_hotregs_on = KERNAL_0.viciv_hotregs_on
;; #ALIAS# viciv_hotregs_off = KERNAL_0.viciv_hotregs_off
;; #ALIAS# m65_speed_tape_cbdos = KERNAL_0.m65_speed_tape_cbdos
;; #ALIAS# m65_speed_restore = KERNAL_0.m65_speed_restore
;; #ALIAS# m65_clr_magictstr = KERNAL_0.m65_clr_magictstr
;; #ALIAS# m65_scrtab_txtwidth = KERNAL_0.m65_scrtab_txtwidth
;; #ALIAS# m65_scrtab_txtheight = KERNAL_0.m65_scrtab_txtheight
+1 -18
View File
@@ -76,12 +76,8 @@ map_DOS_1:
phy
phz
lda #$80
tab ; from now on, zeropage starts from $C000
ldy #$80
lda #$30
taz ; $8000 <- map 16KB RAM from $10000
ldz #$30 ; $8000 <- map 16KB RAM from $10000
lda #$C0
ldx #$C1 ; $4000 <- map 16KB ROM from $20000
@@ -89,19 +85,6 @@ map_DOS_1:
map
bra map_end_no_eom ; no EOM, we do not want interrupts within DOS!
map_NORMAL_from_DOS_1:
php
pha
phx
phy
phz
lda #$00
tab
bra map_NORMAL_common
map_MON_1:
php
+110
View File
@@ -0,0 +1,110 @@
;; #LAYOUT# M65 KERNAL_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Checks if system is in MEGA65 native mode; if so, switches CPU speed to fast/slow for IO routines
; Alters only status bits, all remaining registers preserved
;
; Entry points:
; - m65_speed_iec - at the start of IEC operations
; - m65_speed_tape_cbdos - at the start of tape or CBDOS operations
; - m65_speed_restore - restore current mode standard speed, hide VIC-IV for compatibility mode
!ifdef CONFIG_IEC {
m65_speed_iec:
; If compatibility mode, unlock VIC-IV
jsr M65_MODEGET
pha
bcc @1
jsr viciv_unhide
@1:
; Switch CPU speed to approx. 1 MHz
lda #%01000000
trb VIC_CTRLB
; Disable badlines and slow interrupt emulation
bra m65_speed_tape_cbdos_ME
}
m65_speed_tape_cbdos:
; If compatibility mode, unlock VIC-IV
jsr M65_MODEGET
pha
bcc @1
jsr viciv_unhide
@1:
; Set the maximum possible speed
lda #%01000000
tsb VIC_CTRLB
; FALLTROUGH
m65_speed_tape_cbdos_ME:
; Disable badlines and slow interrupt emulation
lda #$00
sta MISC_EMU
pla
rts
m65_speed_restore:
; Restore proper speed depending on the mode
jsr M65_MODEGET
pha
bcc m65_speed_restore_native
; FALLTROUGH
m65_speed_restore_compat:
; C64 compatibility mode - approx 1 MHz, badlines and slow interrupts enabled
lda #%01000000
trb VIC_CTRLB
; FALLTROUGH
m65_speed_ME_compat:
; Reenable badlines and slow interrupt emulation
lda #$03
sta MISC_EMU
; Hide the VIC-IV
sta VIC_KEY
; Return
pla
rts
m65_speed_restore_native:
; Native mode - maximum speed
lda #%01000000
tsb VIC_CTRLB
; All the special speed modes disable badlines and slow interrupts,
; so there is no need to restore them
pla
rts
@@ -1,31 +0,0 @@
;; #LAYOUT# M65 KERNAL_1 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Tape helper routine
;
; - unlocks VIC-IV
; - switches CPU to fast processing mode and disables badlines
; - stores previous VIC_CTRLB in NXTBIN
;
!ifdef HAS_TAPE {
tape_fast_cpu:
jsr M65_MODEGET
bcc @1
jsr viciv_unhide
@1:
lda VIC_CTRLB
ora #%01000000
sta VIC_CTRLB
sta NXTBIT
lda #$00
sta MISC_EMU
rts
}
+2 -2
View File
@@ -91,8 +91,8 @@ kernalerror_TOP_MEM_RS232:
lda #K_ERR_TOP_MEM_RS232
!ifdef CONFIG_MB_M65 {
; If in native mode, switch back to fast mode
jsr m65_iec_fast
; Restore the proper speed
jsr m65_speed_restore
}
sec
rts
+1 -1
View File
@@ -24,7 +24,7 @@ ACPTR:
!ifdef CONFIG_MB_M65 {
jsr m65dos_check
+bcc m65dos_acptr ; branch if device is handeld by internal DOS
+bcc m65dos_acptr ; branch if device is handeld by internal DOS
}
!ifdef CONFIG_IEC {
+2 -2
View File
@@ -26,8 +26,8 @@ iec_return_success:
+plx_trash_a
!ifdef CONFIG_MB_M65 {
; If in native mode, switch back to fast mode
jsr m65_iec_fast
; Restore the proper speed
jsr m65_speed_restore
}
; Report success
+6 -6
View File
@@ -17,8 +17,8 @@
iec_rx_dispatch:
!ifdef CONFIG_MB_M65 {
; If in native mode, switch to 1 MHz
jsr m65_iec_slow
; Ensure 1 Mhz mode and disabled badlines
jsr m65_speed_iec
}
lda IECPROTO
@@ -33,8 +33,8 @@ iec_rx_dispatch:
iec_rx_byte:
!ifdef CONFIG_MB_M65 { !ifndef CONFIG_IEC_JIFFYDOS {
; If in native mode, switch to 1 MHz
jsr m65_iec_slow
; Ensure 1 Mhz mode and disabled badlines
jsr m65_speed_iec
} }
; Store .X and .Y on the stack - preserve them
@@ -161,8 +161,8 @@ iec_rx_acknowledge:
iec_rx_end:
!ifdef CONFIG_MB_M65 {
; If in native mode, switch back to fast mode
jsr m65_iec_fast
; Restore the proper speed
jsr m65_speed_restore
}
+ply_trash_a
+43 -5
View File
@@ -11,11 +11,18 @@
iec_send_file_name:
ldy #0
ldy #$00
!ifdef CONFIG_MB_M65 {
jsr m65dos_check
+bcc m65dos_send_file_name_loop ; branch if device is handeld by internal DOS
}
iec_send_file_name_loop:
cpy FNLEN
beq iec_send_file_name_done
+beq UNLSN
!ifdef CONFIG_MEMORY_MODEL_60K {
ldx #<FNADDR+0
@@ -27,7 +34,9 @@ iec_send_file_name_loop:
}
iny
; Set Carry flag on the last file name character, to mark EOI
cpy FNLEN
clc
bne @1
@@ -40,8 +49,37 @@ iec_send_file_name_loop:
} else {
jsr iec_tx_byte
}
jmp iec_send_file_name_loop
+bra iec_send_file_name_loop
!ifdef CONFIG_MB_M65 {
m65dos_send_file_name_loop:
cpy FNLEN
+beq UNLSN
!ifdef CONFIG_MEMORY_MODEL_60K {
ldx #<FNADDR+0
jsr peek_under_roms
} else ifdef CONFIG_MEMORY_MODEL_46K_OR_50K {
jsr peek_under_roms_via_FNADDR
} else { ; CONFIG_MEMORY_MODEL_38K
lda (FNADDR),y
}
iny
; Set Carry flag on the last file name character, to mark EOI
cpy FNLEN
clc
bne @1
sec
@1:
; Transmit one character
jsr m65dos_ciout
+bra m65dos_send_file_name_loop
}
iec_send_file_name_done:
jmp UNLSN
}
+2 -2
View File
@@ -21,8 +21,8 @@ iec_turnaround_to_listen:
sei
!ifdef CONFIG_MB_M65 {
; If in native mode, switch to 1 MHz
jsr m65_iec_slow
; Ensure 1 Mhz mode and disabled badlines
jsr m65_speed_iec
}
; Pull DATA, release CLK and ATN (we are not sending commands)
+4 -4
View File
@@ -20,8 +20,8 @@ iec_tx_dispatch:
php ; preserve C flag for EOI indication
!ifdef CONFIG_MB_M65 {
; If in native mode, switch to 1 MHz
jsr m65_iec_slow
; Ensure 1 Mhz mode and disabled badlines
jsr m65_speed_iec
}
lda IECPROTO
@@ -41,9 +41,9 @@ iec_tx_dispatch:
iec_tx_byte:
!ifdef CONFIG_MB_M65 { !ifndef CONFIG_IEC_JIFFYDOS {
; If in native mode, switch to 1 MHz
; Ensure 1 Mhz mode and disabled badlines
php
jsr m65_iec_slow
jsr m65_speed_iec
plp
} }
+2 -2
View File
@@ -39,8 +39,8 @@ iec_tx_command:
; and transmits a byte
!ifdef CONFIG_MB_M65 {
; If in native mode, switch to 1 MHz
jsr m65_iec_slow
; Ensure 1 Mhz mode and disabled badlines
jsr m65_speed_iec
}
clc ; Carry flag set is used for EOI mark
jmp iec_tx_common
+17
View File
@@ -7,6 +7,9 @@
;
; XXX This is suspiciously complicated, most likely something is really wrong with the IEC support
!ifdef CONFIG_IEC {
@@ -57,6 +60,11 @@ load_iec:
jsr TALK
bcs load_iec_error
!ifdef CONFIG_MB_M65 {
jsr m65dos_check
+bcc m65dos_load_part ; branch if device is handeld by internal DOS
}
!ifdef HAS_IEC_BURST {
jsr burst_advertise
}
@@ -83,6 +91,10 @@ load_iec:
jsr load_iec_get_addr_byte
sta EAL+1
!ifdef CONFIG_MB_M65 {
load_iec_m65cont:
}
; If secondary address is 0, override EAL with STAL
lda SA
@@ -126,6 +138,11 @@ load_iec:
load_iec_loop:
!ifdef CONFIG_MB_M65 {
jsr m65dos_check
+bcc m65dos_load_loop ; branch if device is handeld by internal DOS
}
; We are now ready to receive bytes
!ifdef CONFIG_IEC_JIFFYDOS {
jsr iec_rx_dispatch
+3 -6
View File
@@ -18,14 +18,11 @@ open_iec:
; We have a command to send to IEC device
jsr LISTEN
bcc @1
jmp kernalerror_DEVICE_NOT_FOUND
@1:
+bcs kernalerror_DEVICE_NOT_FOUND
lda SA
jsr iec_cmd_open
bcc @2
jmp kernalerror_DEVICE_NOT_FOUND
@2:
+bcs kernalerror_DEVICE_NOT_FOUND
!ifdef CONFIG_MEMORY_MODEL_60K {
; We need our helpers to get to filenames under ROMs or IO area
+1 -1
View File
@@ -15,7 +15,7 @@
TKSA:
!ifdef CONFIG_MB_MEGA65 {
!ifdef CONFIG_MB_M65 {
jsr m65dos_check
+bcc m65dos_tksa ; branch if device is handeld by internal DOS
+4 -4
View File
@@ -29,8 +29,8 @@ dolphindos_load:
}
!ifdef CONFIG_MB_M65 {
; If in native mode, switch to 1 MHz
jsr m65_iec_slow
; Ensure 1 Mhz mode and disabled badlines
jsr m65_speed_iec
}
; FALLTROUGH
@@ -115,8 +115,8 @@ dolphindos_load_no_eoi:
dolphindos_load_end:
!ifdef CONFIG_MB_M65 {
; If in native mode, switch back to fast mode
jsr m65_iec_fast
; Restore the proper speed
jsr m65_speed_restore
}
; Update EAL
clc
+4 -8
View File
@@ -87,10 +87,6 @@ jiffydos_load:
; A trick to shorten EAL update time
ldy #$FF
!ifdef CONFIG_MB_M65 {
; If in native mode, switch to 1 MHz
jsr m65_iec_fast
}
; FALLTROUGH
jiffydos_load_loop_esc:
@@ -195,8 +191,8 @@ jiffydos_load_end:
ldy #$FF
!ifdef CONFIG_MB_M65 {
; If in native mode, switch to 1 MHz
jsr m65_iec_slow
; Ensure 1 Mhz mode and disabled badlines
jsr m65_speed_iec
}
; FALLTROUGH
@@ -280,8 +276,8 @@ jiffydos_load_loop:
jiffydos_load_end:
!ifdef CONFIG_MB_M65 {
; If in native mode, switch back to fast mode
jsr m65_iec_fast
; Restore the proper speed
jsr m65_speed_restore
}
; Save last byte
tax
+4
View File
@@ -13,6 +13,8 @@
jiffydos_wait_line:
!ifdef CONFIG_MB_M65 { ; MEGA65 does not need to wait, but has to waste few cycles
; One might try to optimize the code by checking for disabled screen
; (bit 4 of VIC_SCROLY); problem: VIC checks this bit only once per frame:
; - https://www.lemon64.com/forum/viewtopic.php?t=56582
@@ -31,5 +33,7 @@ jiffydos_wait_line:
jiffydos_wait_line_done:
}
rts
}
+28 -17
View File
@@ -7,16 +7,17 @@
!addr VDOS_INIT = $4020 + 0 * 2
!addr VDOS_CHKUNIT = $4020 + 1 * 2
!addr VDOS_SETUNIT = $4020 + 2 * 2
!addr VDOS_ACPTR = $4020 + 3 * 2
!addr VDOS_CIOUT = $4020 + 4 * 2
!addr VDOS_LISTEN = $4020 + 5 * 2
!addr VDOS_SECOND = $4020 + 6 * 2
!addr VDOS_TALK = $4020 + 7 * 2
!addr VDOS_TKSA = $4020 + 8 * 2
!addr VDOS_UNTLK = $4020 + 9 * 2
!addr VDOS_UNLSN = $4020 + 10 * 2
!addr VDOS_UNITCHK = $4020 + 1 * 2
!addr VDOS_UNITSET = $4020 + 2 * 2
!addr VDOS_UNITNUM = $4020 + 3 * 2
!addr VDOS_ACPTR = $4020 + 4 * 2
!addr VDOS_CIOUT = $4020 + 5 * 2
!addr VDOS_LISTEN = $4020 + 6 * 2
!addr VDOS_SECOND = $4020 + 7 * 2
!addr VDOS_TALK = $4020 + 8 * 2
!addr VDOS_TKSA = $4020 + 9 * 2
!addr VDOS_UNTLK = $4020 + 10 * 2
!addr VDOS_UNLSN = $4020 + 11 * 2
m65dos_init:
@@ -27,24 +28,34 @@ m65dos_init:
jsr (VDOS_INIT)
bra m65dos_end_1
m65dos_chkunit: ; XXX expose to BASIC
m65dos_unitchk: ; XXX expose to BASIC
; Checks is the unit number is supported by the internal DOS
; Input: .A - unit number to check
; Output: Carry set if not supported, otherwise .A contains unit type (0 = SD card, 1 = internal floppy, 2 = RAM disk)
jsr map_DOS_1
jsr (VDOS_CHKUNIT)
jsr (VDOS_UNITCHK)
bra m65dos_end_1
m65dos_setunit: ; XXX expose to BASIC
m65dos_unitset: ; XXX expose to BASIC
; Set the unit number
; Input: .A - unit number, .X - unit type (as in m65dos_chkunit)
; Input: .X - unit number, .A - unit type (as in m65dos_chkunit)
; Output: Carry set means error
jsr map_DOS_1
jsr (VDOS_SETUNIT)
jsr (VDOS_UNITSET)
bra m65dos_end_1
m65dos_unitnum: ; XXX expose to BASIC
; Set the unit number
; Input: .A - unit type (as in m65dos_chkunit)
; Output: .A - unit number, Carry set means error
jsr map_DOS_1
jsr (VDOS_UNITNUM)
bra m65dos_end_1
m65dos_acptr:
@@ -56,7 +67,7 @@ m65dos_acptr:
m65dos_end_1:
jmp map_NORMAL_from_DOS_1 ; ACPTR is slightly faster
jmp map_NORMAL ; ACPTR is slightly faster
m65dos_ciout:
@@ -67,7 +78,7 @@ m65dos_ciout:
m65dos_end_2:
jmp map_NORMAL_from_DOS_1 ; CIOUT is slightly faster
jmp map_NORMAL ; CIOUT is slightly faster
m65dos_listen:
+1 -1
View File
@@ -10,7 +10,7 @@ m65dos_check:
pha
lda IECPROTO
cmp #IEC_ROMDOS
cmp #IEC_CBDOS
beq @1
pla
+2 -2
View File
@@ -12,10 +12,10 @@ m65dos_detect:
; Output: Carry set if not supported, if supported IECPROTO isset to IEC_ROMDOS
pha
jsr m65dos_chkunit
jsr m65dos_unitchk
bcs @1
lda #IEC_ROMDOS
lda #IEC_CBDOS
sta IECPROTO
@1:
pla
+57
View File
@@ -0,0 +1,57 @@
;; #LAYOUT# M65 KERNAL_0 #TAKE
;; #LAYOUT# * * #IGNORE
;
; MEGA65 pseudo-IEC internal DOS support - part of the LOAD routine
;
m65dos_load_part:
; Open channel for loading
lda #$60
jsr m65dos_tksa
jsr m65dos_get_addr_byte
sta EAL+0
jsr m65dos_get_addr_byte
sta EAL+1
jmp load_iec_m65cont
m65dos_get_addr_byte:
jsr m65dos_acptr
bcs @1
lda IOSTATUS
and #K_STS_EOI
bne @1
lda TBTCNT
rts
@1:
pla
pla
jmp load_iec_file_not_found
m65dos_load_loop:
jsr m65dos_acptr
; Handle the byte (store in memory / verify)
jsr lvs_handle_byte_load_verify
+bcs load_iec_error
; Advance pointer to data; it is OK if it advances past $FFFF,
; one autostart technique does exactly this
inw EAL+0
; Check for EOI - if so, this was the last byte
bit IOSTATUS
bvc m65dos_load_loop
; FALLTROUGH
jmp load_iec_loop_end
+3 -3
View File
@@ -16,8 +16,8 @@ SETFLS:
; There are 6 sane ways to implement this routine,
; I hope this one will not cause similarity to CBM code
sta LA
sty SA
stx FA
sta LA ; logical number
sty SA ; secondary address
stx FA ; unit number
rts
+4 -15
View File
@@ -22,20 +22,9 @@ tape_screen_on_motor_off:
!ifdef CONFIG_MB_M65 {
jsr M65_MODEGET
bcc @1
; Restore standard CPU speed settings
; For compatibility mode, restore normal speed settings and hide VIC-IV
lda #$03
sta MISC_EMU
lda NXTBIT
sta VIC_CTRLB
sta VIC_KEY
@1:
rts
jmp m65_speed_restore
} else ifdef CONFIG_MB_U64 {
@@ -64,12 +53,12 @@ tape_screen_off_motor_on:
!ifdef CONFIG_MB_M65 {
; On MEGA65 we need to switch banks everytim we retrieve byte to be stored in memory,
; On MEGA65 we need to switch banks everytime we retrieve byte to be stored in memory,
; additionally we perform advanced tape speed autocallibration - this is all too expensive
; to be handled by 1 MHz CPU - so in case of compatibility mode, switch CPU to fast speed
; (and disable badlines, so we will not have to blank the screen)
jsr tape_fast_cpu
jsr m65_speed_tape_cbdos
} else ifdef CONFIG_MB_U64 {
+1 -1
View File
@@ -48,7 +48,7 @@ tape_head_align:
; Switch CPU to fast mode
!ifdef CONFIG_MB_M65 {
jsr tape_fast_cpu
jsr m65_speed_tape_cbdos
}
!ifdef CONFIG_MB_U64 {
+1
View File
@@ -38,6 +38,7 @@ Mon_Start:
; ********
CLD
CLI
TSY
STY SPH
TSX
Loaded 100 of 118 files, more files were not shown because too many files have changed in this diff. Show more