diff --git a/sources/DSS/.vscode/launch.json b/sources/DSS/.vscode/launch.json index 31f946e..a8f9bf3 100644 --- a/sources/DSS/.vscode/launch.json +++ b/sources/DSS/.vscode/launch.json @@ -85,89 +85,89 @@ // "tmpDir": ".tmp" // }, - { - "type": "dezog", - "request": "launch", - "name": "WTERM Internal Simulator", - "remoteType": "zsim", - "zsim": { - "visualMemory": true, - "memoryModel": "CUSTOM", - "customMemory": { - "slots": [ - { - "name": "PAGE0", - "range": ["0x0000","0x3FFF"], - "banks": [{"index": [0, 255]}], - "initialBank": 0 - }, - { - "name": "PAGE1", - "range": ["0x4000","0x7FFF"], - "banks": [{"index": [0, 255]}], - "initialBank": 1 - }, - { - "name": "PAGE2", - "range": ["0x8000","0xBFFF"], - "banks": [{"index": [0, 255]}], - "initialBank": 2 - }, - { - "name": "PAGE3", - "range": ["0xC000","0xFFFF"], - "banks": [{"index": [0, 255]}], - "initialBank": 3 - } - ], - "ioMmu": [ - "if (portAddress == 0x82) {", - " bank = portValue;", - " PAGE0 = bank;", - "}", - "if (portAddress == 0xA2) {", - " bank = portValue;", - " PAGE1 = bank;", - "}", - "if (portAddress == 0xC2) {", - " bank = portValue;", - " PAGE2 = bank;", - "}", - "if (portAddress == 0xE2) {", - " bank = portValue;", - " PAGE3 = bank;", - "}" - ] - }, - "customCode": { - "debug": false, - "jsPath": "sim/ports.js" - }, - }, - "sjasmplus": [ - { - "path": "wterm.sld" - } - ], - "history": { - "reverseDebugInstructionCount": 1000000, - "spotCount": 10, - "codeCoverageEnabled": true - }, - "startAutomatically": false, - "commandsAfterLaunch": ["-rmv"], - "rootFolder": "${workspaceFolder}", - "topOfStack": "STACK_TOP", - "loadObjs": [ - { - "path": "wterm.exe", - "start": "0x0000" - } - ], - "execAddress": "0x8100", - "smallValuesMaximum": 513, - "tmpDir": ".tmp" - }, + // { + // "type": "dezog", + // "request": "launch", + // "name": "WTERM Internal Simulator", + // "remoteType": "zsim", + // "zsim": { + // "visualMemory": true, + // "memoryModel": "CUSTOM", + // "customMemory": { + // "slots": [ + // { + // "name": "PAGE0", + // "range": ["0x0000","0x3FFF"], + // "banks": [{"index": [0, 255]}], + // "initialBank": 0 + // }, + // { + // "name": "PAGE1", + // "range": ["0x4000","0x7FFF"], + // "banks": [{"index": [0, 255]}], + // "initialBank": 1 + // }, + // { + // "name": "PAGE2", + // "range": ["0x8000","0xBFFF"], + // "banks": [{"index": [0, 255]}], + // "initialBank": 2 + // }, + // { + // "name": "PAGE3", + // "range": ["0xC000","0xFFFF"], + // "banks": [{"index": [0, 255]}], + // "initialBank": 3 + // } + // ], + // "ioMmu": [ + // "if (portAddress == 0x82) {", + // " bank = portValue;", + // " PAGE0 = bank;", + // "}", + // "if (portAddress == 0xA2) {", + // " bank = portValue;", + // " PAGE1 = bank;", + // "}", + // "if (portAddress == 0xC2) {", + // " bank = portValue;", + // " PAGE2 = bank;", + // "}", + // "if (portAddress == 0xE2) {", + // " bank = portValue;", + // " PAGE3 = bank;", + // "}" + // ] + // }, + // "customCode": { + // "debug": false, + // "jsPath": "sim/ports.js" + // }, + // }, + // "sjasmplus": [ + // { + // "path": "wterm.sld" + // } + // ], + // "history": { + // "reverseDebugInstructionCount": 1000000, + // "spotCount": 10, + // "codeCoverageEnabled": true + // }, + // "startAutomatically": false, + // "commandsAfterLaunch": ["-rmv"], + // "rootFolder": "${workspaceFolder}", + // "topOfStack": "STACK_TOP", + // "loadObjs": [ + // { + // "path": "wterm.exe", + // "start": "0x0000" + // } + // ], + // "execAddress": "0x8100", + // "smallValuesMaximum": 513, + // "tmpDir": ".tmp" + // }, { "type": "dezog", @@ -248,6 +248,15 @@ "start": "0x0000" } ], + "memoryViewer": { + "registersMemoryView":[ + "HL", + "DE", + "BC", + "IX", + "IY" + ] + }, "execAddress": "0x8100", "smallValuesMaximum": 513, "tmpDir": ".tmp" diff --git a/sources/DSS/dss.asm b/sources/DSS/dss.asm index b8e2d17..e8a7840 100644 --- a/sources/DSS/dss.asm +++ b/sources/DSS/dss.asm @@ -363,6 +363,16 @@ _EXIT CMD_LINE_TFTP_D DB " tftp://tftp.server.ru:1024/file_in.asm c:\\tmp\\file_out.asm"Z +CMD_LINE_TFTP_D1 + DB " tftp://tftp.server.ru:1024/file_in.asm"Z + +CMD_LINE_TFTP_U + DB " file_up.txt tftp://tftp.server.ru:9999/file_in.asm "Z + +CMD_LINE_TFTP_U1 + DB " file_up.txt"Z + + IN_FILE DS 1024,0 IN_FILE_END diff --git a/sources/DSS/dss_error.asm b/sources/DSS/dss_error.asm new file mode 100644 index 0000000..1fbe81f --- /dev/null +++ b/sources/DSS/dss_error.asm @@ -0,0 +1,96 @@ +; ====================================================== +; DSS Error handler for Sprinter computer +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; License: BSD 3-Clause +; ====================================================== + MODULE DSS_ERROR + +ERR_MAX EQU 0x26 + + +CHECK + RET NC + +PRINT + CALL GET_ERR_MSG + LD C,DSS_PCHARS + RST DSS + LD C,DSS_PCHARS + LD HL, WCOMMON.LINE_END + RST DSS + POP BC ; clear add from stack + LD BC,0x0141 ; and exit + RST DSS + +; ------------------------------------------------------ +; Return pointer to DSS error message +; Inp: A - error code +; Out: HL -> message +; ------------------------------------------------------ +GET_ERR_MSG + CP ERR_MAX+1 + JP C,.GEM_IN_RANGE + LD A,ERR_MAX +.GEM_IN_RANGE + LD HL,.ERR_OFFSETS + PUSH AF + ADD A,A + LD D,0 + LD E,A + ADD HL,DE + LD A,(HL) + INC HL + LD H,(HL) + LD L,A + POP AF + RET + +.MSG_E01 DB "Invalid function"Z +.MSG_E02 DB "Invalid drive number"Z +.MSG_E03 DB "File not found"Z +.MSG_E04 DB "Path not found"Z +.MSG_E05 DB "Invalid handle"Z +.MSG_E06 DB "Too many open files"Z +.MSG_E07 DB "File exist"Z +.MSG_E08 DB "File read only"Z +.MSG_E09 DB "Root overflow"Z +.MSG_E0A DB "No free space"Z +.MSG_E0B DB "Directory not empty"Z +.MSG_E0C DB "Attempt to remove current directory"Z +.MSG_E0D DB "Invalid media"Z +.MSG_E0E DB "Invalid operation"Z +.MSG_E0F DB "Directory exist"Z +.MSG_E10 DB "Invalid filename"Z +.MSG_E11 DB "Invalid EXE-file"Z +.MSG_E12 DB "Not supported EXE-file"Z +.MSG_E13 DB "Permission denied"Z +.MSG_E14 DB "Not ready"Z +.MSG_E15 DB "Seek error"Z +.MSG_E16 DB "Sector not found"Z +.MSG_E17 DB "CRC error"Z +.MSG_E18 DB "Write protect"Z +.MSG_E19 DB "Read error"Z +.MSG_E1A DB "Write error"Z +.MSG_E1B DB "Drive failure"Z +.MSG_E1C DB "Unknown error: 28"Z +.MSG_E1D DB "Unknown error: 29"Z +.MSG_E1E DB "No free memory"Z +.MSG_E1F DB "Invalid memory block"Z +.MSG_E20 DB "Unknown error: 32"Z +.MSG_E21 DB "Extended error: 33"Z +.MSG_E22 DB "Extended error: 34"Z +.MSG_E23 DB "Too many files"Z +.MSG_E24 DB "Too many or too nested folders (>1024)"Z +.MSG_E25 DB "User abort"Z +.MSG_E26 DB "Unknown error"Z + +.ERR_OFFSETS + DW .MSG_E01,.MSG_E02,.MSG_E03,.MSG_E04,.MSG_E05,.MSG_E06,.MSG_E07,.MSG_E08 + DW .MSG_E09,.MSG_E0A,.MSG_E0B,.MSG_E0C,.MSG_E0D,.MSG_E0E,.MSG_E0F,.MSG_E10 + DW .MSG_E11,.MSG_E12,.MSG_E13,.MSG_E14,.MSG_E15,.MSG_E16,.MSG_E17,.MSG_E18 + DW .MSG_E19,.MSG_E1A,.MSG_E1B,.MSG_E1C,.MSG_E1D,.MSG_E1E,.MSG_E1F,.MSG_E20 + DW .MSG_E21,.MSG_E22,.MSG_E23,.MSG_E24,.MSG_E25,.MSG_E26 + + ENDMODULE + \ No newline at end of file diff --git a/sources/DSS/util.asm b/sources/DSS/util.asm index 6dcf3a2..0f81ca7 100644 --- a/sources/DSS/util.asm +++ b/sources/DSS/util.asm @@ -246,6 +246,58 @@ CONV_NIBLE RET ENDIF + +; ---------------------------------------------------- +; Get full current path +; Inp: HP - pointer to buffer for path +; ---------------------------------------------------- + +GET_CUR_DIR + PUSH HL + LD C, DSS_CURDISK + RST DSS + CALL DSS_ERROR.CHECK + ADD A, 65 + LD (HL),A + INC HL + LD (HL),':' + INC HL + LD C, DSS_CURDIR + RST DSS + CALL DSS_ERROR.CHECK + POP HL + CALL ADD_BACK_SLASH + RET + +; ---------------------------------------------------- +; Add back slash to path string +; Inp: HL - pointer to zero ended string with path +; Out: HL - point to end +; ---------------------------------------------------- +ADD_BACK_SLASH + XOR A + ; find end of path +.FIND_EOS + CP (HL) + JR Z,.IS_EOS + INC HL + JR .FIND_EOS + ; check last symbol is '\'' and add if not +.IS_EOS + DEC HL + LD A,(HL) + CP "\\" + JR Z,.IS_SEP + INC HL + LD (HL),"\\" +.IS_SEP + ; mark new end of string + INC HL + LD (HL),0x0 + RET + + + ENDMODULE ENDIF \ No newline at end of file diff --git a/sources/DSS/wcommon.asm b/sources/DSS/wcommon.asm index 028a3ab..6c9f966 100644 --- a/sources/DSS/wcommon.asm +++ b/sources/DSS/wcommon.asm @@ -22,6 +22,7 @@ CHECK_ERROR LD B,3 POP HL ; ret addr reset ENDIF + ; ------------------------------------------------------ ; Program exit point ; ------------------------------------------------------ diff --git a/sources/DSS/wtftp.asm b/sources/DSS/wtftp.asm index 0d0f0ea..d1ebf2f 100644 --- a/sources/DSS/wtftp.asm +++ b/sources/DSS/wtftp.asm @@ -25,11 +25,13 @@ EXE_VERSION EQU 1 ; Timeout to wait ESP response DEFAULT_TIMEOUT EQU 2000 - DEFDEVICE SPRINTER, 0x4000, 256, 0,1,2,3 + DEVICE NOSLOT64K - SLDOPT COMMENT WPMEM, LOGPOINT, ASSERTION +; DEFDEVICE SPRINTER, 0x4000, 256, 0,1,2,3 - DEVICE SPRINTER ;NOSLOT64K +; SLDOPT COMMENT WPMEM, LOGPOINT, ASSERTION + +; DEVICE SPRINTER ;NOSLOT64K IF DEBUG == 1 INCLUDE "dss.asm" @@ -68,13 +70,18 @@ START IF DEBUG == 1 LD IX,CMD_LINE_TFTP_D - LD SP, STACK_TOP - JP MAIN_LOOP + LD SP, STACK_TOP ENDIF CALL PARSE_CMD_LINE - CALL OPEN_LOCAL_FILE + ;CALL OPEN_LOCAL_FILE + CALL DISPLAY_MODE + + + IF DEBUG == 1 + JP MAIN_LOOP + ENDIF CALL ISA.ISA_RESET @@ -126,13 +133,12 @@ PARSE_CMD_LINE ; Work Mode "Download" ; handle parameter URL - LD DE,0x0007 - ADD HL,DE CALL GET_SRV_PARAMS CALL SKIP_SPACES ; handle lfn CALL GET_LFN + CALL COPY_LFN RET .PLC_UPLOAD @@ -142,6 +148,11 @@ PARSE_CMD_LINE CALL GET_LFN CALL SKIP_SPACES + + LD DE,TFTF_START + CALL @UTIL.STARTSWITH + JR NZ,OUT_USAGE_MSG + CALL GET_SRV_PARAMS RET @@ -161,6 +172,10 @@ OUT_USAGE_MSG ; ------------------------------------------------------ GET_SRV_PARAMS PUSH BC,DE + + LD DE,0x0007 + ADD HL,DE + LD DE,SRV_NAME .GSN_NEXT LD A,(HL) @@ -182,17 +197,15 @@ GET_SRV_PARAMS INC HL LD A,(HL) CP A,'/' ; end slash - JR .GSN_EN + JR Z,.GSN_EN CP A,'0' JP M,.GSN_EPN - CP A,'9' ; >'9'? + CP A,0x3A ; >'9'? JP P,.GSN_EPN LD (DE),A INC DE - DEC B - JR Z,.GSN_EPN ; too long number - JR .GSNP_NXT - ; end of numbers + DJNZ .GSNP_NXT + ; too long number .GSN_EPN @@ -216,8 +229,10 @@ GET_SRV_PARAMS .GDNF_NXT INC HL LD A,(HL) - OR A - JR Z,.GDNF_END +; OR A +; JR Z,.GDNF_END + CP 0x21 + JP M,.GDNF_END LD (DE),A INC DE DEC B @@ -243,32 +258,38 @@ GET_SRV_PARAMS ; ------------------------------------------------------ GET_LFN PUSH BC,DE - - XOR B LD DE,LOC_FILE + +.GLF_NXT LD A,(HL) OR A - JR Z,.GLF_E + JR Z,.GLF_END CP ' ' - JR Z,.GLF_E - ; CP "\\" - ; CALL Z,.GLF_SET_DIR - ; CP ":" - ; CALL Z,.GLF_SET_DIR + JR Z,.GLF_END CP 0x21 JP M,.GLF_IFN CP '*' JP Z,.GLF_IFN + CP ':' + CALL .GLF_HAVE_PATH + CP "\\" + CALL .GLF_HAVE_PATH + LD (DE),A + INC HL + INC DE + JR .GLF_NXT -.GLF_E - +.GLF_END POP DE,BC RET ; set flag to not add current dir -.GLF_SET_DIR - LD B,1 +.GLF_HAVE_PATH + JR NZ, .GLF_NHP + LD IY,HAVE_PATH + INC (IY+0) +.GLF_NHP RET ; Illegal file name @@ -276,6 +297,30 @@ GET_LFN PRINTLN MSG_ERR_LFN JP OUT_USAGE_MSG +; ------------------------------------------------------ +; Check local file name for empty and fill it from +; remote file name +; ------------------------------------------------------ +COPY_LFN + LD HL,LOC_FILE + LD A, (HL) + OR A + RET NZ ; ok, it is not empty + CALL UTIL.GET_CUR_DIR + //LD DE,HL + LD DE,REM_FILE +.CLFN_NXT + LD A,(DE) + LD (HL),A + OR A + RET Z + INC HL + INC DE + JR .CLFN_NXT + + + + ; ------------------------------------------------------ ; Open local file for upload or download ; RO - for upload @@ -302,6 +347,45 @@ SKIP_SPACES JR SKIP_SPACES +; ------------------------------------------------------ +; Display current working mode +; ------------------------------------------------------ +DISPLAY_MODE + LD A,(WORK_MODE) + CP A,WM_UPLOAD + JR .DM_UPLOAD + ; Download + PRINT MSG_MODE_D + PRINT REM_FILE + PRINT MSG_MODE_D_S + PRINT SRV_NAME + PRINT MSG_MODE_D_T + PRINTLN LOC_FILE + RET + ; Upload +.DM_UPLOAD + PRINT MSG_MODE_U + PRINT LOC_FILE + PRINT MSG_MODE_U_S + PRINT SRV_NAME + PRINT MSG_MODE_U_T + PRINTLN REM_FILE + RET + +MSG_MODE_D + DB "Download file "Z +MSG_MODE_D_S + DB " from server "Z +MSG_MODE_D_T + DB " to file "Z + +MSG_MODE_U + DB "Upload file "Z +MSG_MODE_U_S + DB " to server "Z +MSG_MODE_U_T + DB " to file "Z + ; ------------------------------------------------------ ; Custom messages ; ------------------------------------------------------ @@ -314,7 +398,7 @@ MSG_ERR_CMD MSG_HLP DB "\r\nUse: wtftp.exe tftp://server[:port]/filename filename - to download file from server;\r\n" - DB "\twtftp.exe filename tftp://server[:port]/filename - to upload file to server.\r\n"Z + DB " wtftp.exe filename tftp://server[:port]/filename - to upload file to server.\r\n"Z MSG_TX_ERROR DB "Transmitter not ready"Z @@ -357,12 +441,18 @@ SRV_PORT REM_FILE DS 128,0 +; Name of the local file LOC_FILE DS 128,0 +; Local file handle LOC_FH DW 0 +; Not null if local file name contains path +HAVE_PATH + DB 0 + ; ------------------------------------------------------ ; Custom commands ; ------------------------------------------------------ @@ -377,6 +467,7 @@ BUFF_TEST1 DS RS_BUFF_SIZE,0 ENDMODULE INCLUDE "wcommon.asm" + INCLUDE "dss_error.asm" ;INCLUDE "util.asm" INCLUDE "isa.asm" INCLUDE "esplib.asm"