diff --git a/README.md b/README.md index 9ddad30..f3162f3 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,22 @@ ## Overview -The Sharp MZ80A as with most vintage computers had limited storage. In order to expand the storage it is often the case that the resident software has to be enhanced which was impossible -given the storage space (ie. 4K Monitor rom). The Sharp MZ80A has a 4K Monitor ROM, a 2K User ROM/RAM and space within the memory map to add a further 4K ROM typically for the floppy disk -drive. +The Sharp MZ80A came with 48K RAM and 4K ROM and apart from the option to add a 2K User RAM/ROM and a 4K Floppy Drive ROM, there was no further possibility to expand the machine memory +capabilities at the hardware level and thus no additional firmware could be added for use at power-on. Add-ons had to rely on loading control firmware into RAM via tape or floppy, thus depleting valuable application space. Some machines of the same era +utilised a scheme called 'banking' whereby much larger memories would occupy a smaller block within the CPU address space and be selected according to features required and hardware attached. The +BBC Micro was such a machine with upto 16 banks of 16Kb, it made the machine much more useable. One of the seperate projects I've been working on was a 40/80 Column switchable display and colour output. This upgrade requires different software, either a complete rewrite of the original monitor or a patched copy for 80 column mode. Wanting to keep the machine as original as possible, using a rewritten ROM is out of the question thus I would need 2 ROMS, original for 40Column and a patched one for 80Column. -Thus was born the need for Rom Paging, ie. Use a modern Flash RAM to house multiple 4K Roms which can be *switched in* according to the hardware upgrade. +Thus was born the need for Rom Paging in the Sharp MZ80A, ie. Use a modern Flash RAM to house multiple 4K Roms which can be *switched in* to the 4K Monitor ROM address space according to the +hardware upgrade being used. It was also seen when using large Flash RAM's it was possible to store programs that would normally be present on tape or floppy and load at much higher speed making use of the computer that much easier. -This upgrade uses the 4K Monitor ROM and 2K User ROM space to map in 2x512Kbyte Flash RAM's providing paged roms and a Rom Filing System storing most commonly used programs. +This upgrade goes a bit further and uses the 4K Monitor ROM and 2K User ROM space to map in 2x512Kbyte Flash RAM's providing multiple paged roms (theoretical 256 x 2K slots and 128 x 4K slots) +and the required custom software to control the banking called the Rom Filing System. This page along with the [CP/M](/sharpmz-upgrades-cpm) page forms the start of the RFS documentation which is still in its infancy. Within this repository are the schematics, PCB Gerber files and the software to implement the Rom Filing System hardware and software. diff --git a/software/asm/cbios.asm b/software/asm/cbios.asm index 16a3cec..87629c6 100644 --- a/software/asm/cbios.asm +++ b/software/asm/cbios.asm @@ -2087,7 +2087,7 @@ SKIPDUMP: POP HL ; HL = Start ; DE = End -DUMPX: LD A,1 +DUMPX: LD A,23 DUM1: LD (TMPCNT),A DUM3: LD B,010h LD C,02Fh @@ -2102,9 +2102,7 @@ DUM2: CALL SPHEX CP 020h JR NC,L0D51 LD A,02Eh -L0D51: ;CALL ?ADCN - ;CALL ?PRNT3 - CALL ?PRNT +L0D51: CALL ?PRNT LD A,(DSPXY) INC C SUB C @@ -2116,12 +2114,6 @@ L0D51: ;CALL ?ADCN SBC HL,DE POP HL JR NC,DUM7 - LD A,0F8h - LD (0E000h),A - NOP - LD A,(0E001h) - CP 0FEh - JR NZ,L0D78 L0D78: DJNZ DUM2 LD A,(TMPCNT) DEC A @@ -2138,8 +2130,8 @@ DUM4: CALL ?CHKKY DUM5: CP 'U' JR NZ,DUM6 PUSH DE - LD DE,000FFH - SCF + LD DE,00100H + OR A SBC HL,DE POP DE LD A,8 diff --git a/software/asm/include/RFS_Definitions.asm b/software/asm/include/RFS_Definitions.asm index 86da4c5..5d86040 100644 --- a/software/asm/include/RFS_Definitions.asm +++ b/software/asm/include/RFS_Definitions.asm @@ -55,15 +55,14 @@ MELDY EQU 00030h MONIT: EQU 00000h SS: EQU 00089h ST1: EQU 00095h -MSGE1 EQU 00118h HLHEX EQU 00410h _2HEX EQU 0041Fh ?MODE: EQU 0074DH ?KEY EQU 008CAh PRNT3 EQU 0096Ch -MSG?2 EQU 000F7h ?ADCN EQU 00BB9h ?DACN EQU 00BCEh +?DSP: EQU 00DB5H ?BLNK EQU 00DA6h ?DPCT EQU 00DDCh PRTHL: EQU 003BAh @@ -73,6 +72,11 @@ DPCT: EQU 00DDCh DLY12: EQU 00DA7h DLY12A: EQU 00DAAh ?RSTR1: EQU 00EE6h +MOTOR: EQU 006A3H +CKSUM: EQU 0071AH +GAP: EQU 0077AH +WTAPE: EQU 00485H +MSTOP: EQU 00700H ; Debugging ENADEBUG EQU 0 ; Enable debugging logic, 1 = enable, 0 = disable @@ -291,6 +295,15 @@ SDDIR_EXEC EQU 019H SDDIR_FNSZ EQU FNSIZE SDDIR_ENTSZ EQU 32 +; +; Rom Filing System constants for the SD Card. +; +SDDIR_DIRENT EQU 256 ; Directory entries in the RFS directory. +SDDIR_DIRENTSZ EQU 32 ; Size of a directory entry. +SDDIR_DIRSIZE EQU SDDIR_DIRENT * SDDIR_DIRENTSZ ; Total size of the directory. +SDDIR_BLOCKSZ EQU 65536 ; Size of a file block per directory entry. +SDDIR_IMGSZ EQU SDDIR_DIRSIZE + (SDDIR_DIRENT * SDDIR_BLOCKSZ) ; Total size of the RFS image. + ;----------------------------------------------- ; SA-1510 MONITOR WORK AREA (MZ80A) ;----------------------------------------------- @@ -350,20 +363,23 @@ TMPLINECNT: EQU 01021H ; Tempo TMPSTACKP: EQU 01023H ; Temporary stack pointer save. SDVER: EQU 01025H SDCAP: EQU 01026H -; Variables sharing the CMT buffer, normally the CMT and SD are not used at the same -; time. This frees up memory needed by the SD card. +; Variables sharing the BUFER buffer, normally the BUFER is only used to get keyboard input and so long as data in BUFER is processed +; before calling the CMT/SD commands and not inbetween there shouldnt be any issue. Also the space used is at the top end of the buffer which is not used so often. +; This frees up memory needed by the CMT and SD card. SECTORBUF: EQU 0CE00H ; Working buffer to place an SD card sector. -SDBYTECNT EQU COMNT+2 ; Bytes to read/write to/from a sector. -SDOFFSET EQU COMNT+4 ; Offset into sector prior to data read/write. -SDSTARTSEC EQU COMNT+6 ; Starting sector of data to read/write from/to SD card. -SDLOADADDR EQU COMNT+10 ; Address to read/write data from/to SD card. -SDLOADSIZE EQU COMNT+12 ; Total remaining byte count data to read/write from/to SD card. -SDAUTOEXEC EQU COMNT+14 ; Flag to indicate if a loaded image should be executed (=0xFF) -SDBUF: EQU COMNT+15 ; SD Card command fram buffer for the command and response storage. -DIRSECBUF: EQU COMNT+26 ; Directory sector in cache. -RESULT: EQU COMNT+27 -BYTECNT: EQU COMNT+29 -WRITECNT: EQU COMNT+31 +SDSTARTSEC EQU BUFER+50+0 ; Starting sector of data to read/write from/to SD card. +SDLOADADDR EQU BUFER+50+4 ; Address to read/write data from/to SD card. +SDLOADSIZE EQU BUFER+50+6 ; Total remaining byte count data to read/write from/to SD card. +SDAUTOEXEC EQU BUFER+50+8 ; Flag to indicate if a loaded image should be executed (=0xFF) +SDBUF: EQU BUFER+50+9 ; SD Card command fram buffer for the command and response storage. +DIRSECBUF: EQU BUFER+50+20 ; Directory sector in cache. +DUMPADDR: EQU BUFER+50+22 ; Address used by the D(ump) command so that calls without parameters go onto the next block. +CMTLOLOAD: EQU BUFER+50+24 ; Flag to indicate that a tape program is loaded into hi memory then shifted to low memory after ROM pageout. +CMTCOPY: EQU BUFER+50+25 ; Flag to indicate that a CMT copy operation is taking place. +CMTAUTOEXEC:EQU BUFER+50+26 ; Auto execution flag, run CMT program when loaded if flag clear. +DTADRSTORE: EQU BUFER+50+27 ; Backup for load address if actual load shifts to lo memory or to 0x1200 for copy. +SDCOPY: EQU BUFER+50+29 ; Flag to indicate an SD copy is taking place, either CMT->SD or SD->CMT. +RESULT: EQU BUFER+50+30 ; Result variable needed for interbank calls when a result is needed. ; Quickdisk work area ;QDPA EQU 01130h ; QD code 1 diff --git a/software/asm/rfs.asm b/software/asm/rfs.asm index 7403140..d6daaef 100644 --- a/software/asm/rfs.asm +++ b/software/asm/rfs.asm @@ -109,14 +109,13 @@ BKSW0to7: PUSH AF PUSH AF LD A, ROMBANK7 ; Required bank to call. ; -BKSW0_0: PUSH BC ; Save BC for caller. - LD BC, BKSWRET0 ; Place bank switchers return address on stack. - PUSH BC - LD (RFSBK2), A ; Bank switch in user rom space, A=bank. +BKSW0_0: PUSH HL ; Place function to call on stack + LD HL, BKSWRET0 ; Place bank switchers return address on stack. + EX (SP),HL LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it. + LD (RFSBK2), A ; Bank switch in user rom space, A=bank. JP (HL) ; Jump to required function. -BKSWRET0: POP BC - POP AF ; Get bank which called us. +BKSWRET0: POP AF ; Get bank which called us. LD (RFSBK2), A ; Return to that bank. POP AF RET ; Return to caller. @@ -161,7 +160,8 @@ SIGNON1: CALL DPCT DEC E JR NZ,SIGNON1 LD DE,MSGSON ; Sign on message, - RST 018h + LD HL,PRINTMSG + CALL BKSW0to6 LD HL, SDINIT ; SD Card Initialisation CALL BKSW0to2 ; Call the initialisation routine. @@ -180,7 +180,7 @@ ST1X: CALL NL ; Comma CMDCMP: LD HL,CMDTABLE CMDCMP0: LD DE,BUFER+1 ; First command byte after the * prompt. LD A,(HL) - CP 00DH + CP 000H JR Z,ST1X ; Skip processing on lines where just CR pressed. BIT 7,A ; Bit 7 set on command properties indicates table end, exit if needed. JR NZ,CMDNOCMP @@ -234,7 +234,8 @@ CMDCMP6: LD DE,CMDCMPEND ; Put r JP (HL) CMDNOCMP: LD DE,MSGBADCMD - RST 018H + LD HL,PRINTMSG + CALL BKSW0to6 CMDCMPEND: JP ST1X ; Monitor command table. This table contains the list of recognised commands along with the @@ -257,13 +258,16 @@ CMDTABLE: DB 000H | 000H | 000H | 001H ; Bit 2 DB 000H | 000H | 018H | 001H DB 'D' ; Dump Memory. DW DUMPX + DB 000H | 000H | 010H | 002H + DB "EC" ; Erase file. + DW ERASESD DB 000H | 000H | 008H | 001H DB 'F' ; RFS Floppy boot code. DW FLOPPY DB 000H | 000H | 008H | 001H DB 0AAH ; Original Floppy boot code. DW FDCK - DB 000H | 000H | 018H | 001H + DB 000H | 000H | 030H | 001H DB 'H' ; Help screen. DW HELP DB 000H | 000H | 000H | 002H @@ -287,10 +291,10 @@ CMDTABLE: DB 000H | 000H | 000H | 001H ; Bit 2 DB 000H | 000H | 000H | 002H DB "LR" ; Load from ROM DW LOADROM - DB 000H | 000H | 000H | 004H + DB 000H | 000H | 010H | 004H DB "LCNX" ; Load from SDCARD without auto execution. DW LOADSDCARDX - DB 000H | 000H | 000H | 002H + DB 000H | 000H | 010H | 002H DB "LC" ; Load from SD CARD DW LOADSDCARD DB 000H | 000H | 020H | 001H @@ -305,6 +309,9 @@ CMDTABLE: DB 000H | 000H | 000H | 001H ; Bit 2 DB 000H | 000H | 038H | 001H DB 'R' ; Memory test. DW MEMTEST + DB 000H | 000H | 018H | 004H + DB "SD2T" ; Copy SD Card to Tape. + DW SD2TAPE DB 000H | 000H | 010H | 002H DB "SC" ; Save to SD CARD DW SAVESDCARD @@ -314,6 +321,9 @@ CMDTABLE: DB 000H | 000H | 000H | 001H ; Bit 2 DB 000H | 000H | 020H | 001H DB 'S' ; Save to CMT DW SAVEX + DB 000H | 000H | 018H | 004H + DB "T2SD" ; Copy Tape to SD Card. + DW TAPE2SD DB 000H | 000H | 038H | 001H DB 'T' ; Timer test. DW TIMERTST @@ -540,8 +550,8 @@ DIRROM: DI ; Disab LD (TMPLINECNT),A ; LD DE,MSGRDIRLST ; Print out header. - RST 018h - CALL NL + LD HL,PRINTMSG + CALL BKSW0to6 ; ; Scan MROM Bank ; B = Bank Page @@ -712,11 +722,10 @@ LOADROM1: DI ; LD A,(ROMBK1) LD (RFSBK1), A - LD DE,MSGLDROM - RST 018H - LD DE,NAME - RST 018H - CALL NL + LD DE,MSGLOAD+1 ; Skip initial CR. + LD BC,NAME + LD HL,PRINTMSG + CALL BKSW0to6 LD A,(WRKROMBK1) LD (RFSBK1), A @@ -727,9 +736,9 @@ LOADROM1: DI LROMNTFND: POP HL ; Dont need execute flag anymore so waste it. LD A,(ROMBK1) LD (RFSBK1),A + LD HL,PRINTMSG LD DE,MSGNOTFND ; Not found - RST 018h - + CALL BKSW0to6 LOADROMEND: EI RET @@ -738,11 +747,12 @@ LOADROMEND: EI ; LROMLOAD: PUSH BC ; - LD DE,MSGLDROM - RST 018H - LD DE,NAME - RST 018H - CALL NL + PUSH BC + LD DE,MSGLOAD+1 + LD BC,NAME + LD HL,PRINTMSG + CALL BKSW0to6 + POP BC ; LD A,B LD (WRKROMBK1),A @@ -838,25 +848,6 @@ LROMLOAD5: POP HL ; Retri JP (HL) ; Execution address. LROMLOAD9: RET - - ; Load a program from the SD Card into RAM and/or execute it. - ; - ; DE points to a number or filename to load. -LOADSDCARDX:LD A,0FFH - JR LOADSDCARD0 -LOADSDCARD: LD A,000H -LOADSDCARD0:LD (SDAUTOEXEC),A - PUSH DE - LD HL,0FFFFh ; Tag the filenumber as invalid. - LD (TMPCNT), HL - CALL ConvertStringToNumber ; See if a file number was given instead of a filename. - JR NZ, LOADSDCARD1 ; - LD (TMPCNT), HL ; Store filenumber making load by filenumber valid. -LOADSDCARD1:POP DE - LD HL,LOADSDE - CALL BKSW0to2 ; Call the main functionality in Bank2. -LOADSDCARD2:RET - ;------------------------------------------------------------------------------- ; END OF RFS COMMAND FUNCTIONS. ;------------------------------------------------------------------------------- @@ -864,21 +855,11 @@ LOADSDCARD2:RET ;-------------------------------------- ; - ; Message table + ; Message table - Refer to bank 6 for + ; all messages. ; ;-------------------------------------- -MSGSON: DB "+ RFS ", 0ABh, "1.1 **",00DH -MSGOK: DB "OK!", 00DH -MSGNOTFND: DB "NOT FOUND", 00DH -MSGRDIRLST: DB "ROM DIRECTORY:", 00DH -MSGTRM: DB 00DH -MSGSV: DB "FILENAME? ", 00DH -MSGBADCMD: DB "???", 00DH -MSGLDROM: DB "LOADING ", 00DH - - - ; Bring in additional resources. USE_CMPSTRING: EQU 1 USE_SUBSTRING: EQU 0 diff --git a/software/asm/rfs_bank1.asm b/software/asm/rfs_bank1.asm index 1388465..ad3ee0f 100644 --- a/software/asm/rfs_bank1.asm +++ b/software/asm/rfs_bank1.asm @@ -89,14 +89,13 @@ BKSW1to7: PUSH AF PUSH AF LD A, ROMBANK7 ; Required bank to call. ; -BKSW1_0: PUSH BC ; Save BC for caller. - LD BC, BKSWRET1 ; Place bank switchers return address on stack. - PUSH BC - LD (RFSBK2), A ; Bank switch in user rom space, A=bank. +BKSW1_0: PUSH HL ; Place function to call on stack + LD HL, BKSWRET1 ; Place bank switchers return address on stack. + EX (SP),HL LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it. + LD (RFSBK2), A ; Bank switch in user rom space, A=bank. JP (HL) ; Jump to required function. -BKSWRET1: POP BC - POP AF ; Get bank which called us. +BKSWRET1: POP AF ; Get bank which called us. LD (RFSBK2), A ; Return to that bank. POP AF RET ; Return to caller. @@ -133,9 +132,9 @@ FLOPPY: PUSH DE ; P CP 00Dh ; JR NZ,GETBOOTDSK ; CALL DSKINIT ; Initialise disk and flags. -L000F: CALL NL ; Prompt for the boot drive as non given in call. - LD DE,BOOTDRV ; - CALL MSG ; +L000F: LD DE,MSGBOOTDRV ; + LD HL,PRINTMSG + CALL BKSW1to6 LD DE,011A3H ; CALL GETL ; LD A,(DE) ; @@ -164,11 +163,12 @@ L0049: LD C,(HL) ; INC HL ; INC DE ; DJNZ L0049 ; - CALL NL ; Ok, we have a bootable disk, so indicate we are booting it... - LD DE,IPLLOAD ; - CALL MSG ; + LD DE,MSGIPLLOAD ; + LD HL,PRINTMSG + CALL BKSW1to6 LD DE,0CE07H ; Program name stored at 8th byte in boot sector. - CALL MSG ; + LD HL,PRTFN + CALL BKSW1to6 LD HL,(0CE16H) ; Get the load address LD (IX+005H),L ; And store in parameter block at 100D/100E LD (IX+006H),H ; @@ -187,13 +187,12 @@ NOTCPM: LD HL,(0CE14H) ; G LD HL,(0CE18H) ; Get the execution address JP (HL) ; And execute. -DSKLOADERR:LD DE,LOADERR ; Loading error message +DSKLOADERR:LD DE,MSGLOADERR ; Loading error message JR L008F ; (+003h) -L008C: LD DE,DSKNOTMST ; This is not a boot/master disk message. -L008F: CALL NL - CALL MSG - CALL NL +L008C: LD DE,MSGDSKNOTMST ; This is not a boot/master disk message. +L008F: LD HL,PRINTMSG + CALL BKSW1to6 LD DE,ERRTONE ; Play error tone. CALL MELDY ; @@ -493,14 +492,13 @@ L0300: IN A,(0D8H) ; Sta ;-------------------------------------- ; - ; Message table + ; Message table - Refer to bank 6 for + ; all messages. ; ;-------------------------------------- -BOOTDRV: DB "FLOPPY BOOT DRIVE ?", 00DH -LOADERR: DB "DISK LOADING ERROR", 00DH -IPLLOAD: DB "DISK LOADING ", 00DH + + ; Error tone. ERRTONE: DB "A0", 0D7H, "ARA", 0D7H, "AR", 00DH -DSKNOTMST: DB "THIS IS NOT A BOOT DISK", 00Dh ; Identifier to indicate this is a valid boot disk DSKID: DB 002H, "IPLPRO" diff --git a/software/asm/rfs_bank2.asm b/software/asm/rfs_bank2.asm index 6c25ef4..eb0c922 100644 --- a/software/asm/rfs_bank2.asm +++ b/software/asm/rfs_bank2.asm @@ -86,18 +86,70 @@ BKSW2to7: PUSH AF PUSH AF LD A, ROMBANK7 ; Required bank to call. ; -BKSW2_0: PUSH BC ; Save BC for caller. - LD BC, BKSWRET2 ; Place bank switchers return address on stack. - PUSH BC - LD (RFSBK2), A ; Bank switch in user rom space, A=bank. +BKSW2_0: PUSH HL ; Place function to call on stack + LD HL, BKSWRET2 ; Place bank switchers return address on stack. + EX (SP),HL LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it. + LD (RFSBK2), A ; Bank switch in user rom space, A=bank. JP (HL) ; Jump to required function. -BKSWRET2: POP BC - POP AF ; Get bank which called us. +BKSWRET2: POP AF ; Get bank which called us. LD (RFSBK2), A ; Return to that bank. POP AF RET ; Return to caller. + + ;------------------------------------------------------------------------------- + ; GENERAL PURPOSE FUNCTIONS. + ;------------------------------------------------------------------------------- + + ; Method to multiply a 16bit number by another 16 bit number to arrive at a 32bit result. + ; Input: DE = Factor 1 + ; BC = Factor 2 + ; Output:DEHL = 32bit Product + ; +MULT16X16: LD HL,0 + LD A,16 +MULT16X1: ADD HL,HL + RL E + RL D + JR NC,$+6 + ADD HL,BC + JR NC,$+3 + INC DE + DEC A + JR NZ,MULT16X1 + RET + + ; Method to add a 16bit number to a 32bit number to obtain a 32bit product. + ; Input: DEHL = 32bit Addend + ; BC = 16bit Addend + ; Output:DEHL = 32bit sum. + ; +ADD3216: ADD HL,BC + EX DE,HL + LD BC,0 + ADC HL,BC + EX DE,HL + RET + + ; Method to add two 32bit numbers whilst calculating the SD Start Sector. + ; Input: DEHL = 32bit Addend + ; (SDSTARTSEC) = 32bit Addend + ; Output: (SDSTARTSEC) = 32bit Sum. + ; Output; DEHL = 32bit Sum. + ; +ADD32: LD BC,(SDSTARTSEC+2) + ADD HL,BC + LD (SDSTARTSEC+2),HL + LD BC,(SDSTARTSEC) + EX DE,HL + ADC HL,BC + LD (SDSTARTSEC),HL + EX DE,HL + RET + + + ;------------------------------------------------------------------------------- ; START OF SD CONTROLLER FUNCTIONALITY ;------------------------------------------------------------------------------- @@ -466,30 +518,28 @@ LBATOADDR: LD HL,(SDSTARTSEC+1) RET - ; Method to read a sector or partial sector contents to an SD Card. ; ; This method was originally a C routine I was using for FatFS but optimised it (still more can be done). The C->ASM is not so optimal. ; - ; Input: Memory variables: SDBYTECNT = unsigned int count. - The count of bytes to read. - ; SDOFFSET = unsigned int offset. - The offset in the 512 byte sector to commence read. - ; SDSTARTSEC= unsigned long sector. - The sector number or direct byte address for older cards. This is big endian as per card. - ; SDLOADADDR= unsigned char BYTE *buf - Pointer to a buffer where the bytes should be stored - ; Output: A = 0 - All ok. A > 0 - error occurred. + ; Input: Memory variables: SDSTARTSEC= unsigned long sector. - The sector number or direct byte address for older cards. This is big endian as per card. + ; HL: Address where to store data read from sector. + ; BC: Size of data to read, upto a sector size. + ; Output: A: 0 - All ok. A > 0 - error occurred. + ; HL: End address of data loaded, ; -SD_READ: LD A,0 +SD_READ: PUSH HL ; Store the load address. + PUSH BC ; Store the read size. + LD A,0 CALL SPICS ; Set CS low (active). LD HL,(SDCAP) ; Test to see if CT_BLOCK is available. LD H,0 LD A,CT_BLOCK AND L - JP NZ,SD_READ3 ; If it has CT_BLOCK then use sector numbers otherwise multiply up to bytes. + JP NZ,SD_READ1 ; If it has CT_BLOCK then use sector numbers otherwise multiply up to bytes. CALL LBATOADDR ; Multiply the sector by 512 for byte addressing on older cards. -SD_READ3: LD A,1 - LD (RESULT),A - - ; A = ACMD to send +SD_READ1: ; A = ACMD to send ; LHED = Argument, ie. ACMD = A, L, H, E, D, CRC LD A,CMD17 ; Send CMD17 to read a sector. LD (SDBUF),A @@ -500,142 +550,85 @@ SD_READ3: LD A,1 CALL SDCMDNP ; Execute SD Command, parameters already loaded into command buffer. LD A,(SDBUF+6) ; Fetch result and store. AND A - JP NZ,SD_READ4 + JP NZ,SD_READ6 LD HL,1000 ; Sit in a tight loop waiting for the data packet arrival (ie. not 0xFF). -SD_READ7: PUSH HL +SD_READ2: PUSH HL LD HL,200 CALL T_DELAY CALL SPIIN POP HL CP 255 - JP NZ,SD_READ6 + JP NZ,SD_READ3 DEC HL LD A,H OR L - JR NZ,SD_READ7 + JR NZ,SD_READ2 -SD_READ6: CP 254 ; Data? If not exit with error code. - JP NZ,SD_READ4 +SD_READ3: CP 254 ; Data? If not exit with error code. + JP NZ,SD_READ6 - LD DE,(SDOFFSET) ; Get offset. - LD HL,SD_SECSIZE+2 ; Size of sector + 2 CRC bytes. - AND A - SBC HL,DE ; Subtract the offset - LD DE,(SDBYTECNT) ; Get count. - AND A - SBC HL,DE ; Subtract the count - LD (BYTECNT),HL ; We are left with number of bytes we dont want to read. - - LD BC,(SDOFFSET) ; Check offset, if not zero then skip offset bytes. - LD A,B - OR C - JP Z,SD_READ11 - CALL SPISKIP - -SD_READ11: LD HL,(SDLOADADDR) ; Get the load address, check to see that it is not NULL before receiving. - LD A,H - OR L - JP Z,SD_READ12 - -SD_READ15: PUSH HL ; Start reading bytes into the buffer. + LD HL,SD_SECSIZE ; Size of full sector + 2 bytes CRC. + POP BC + OR A + SBC HL,BC ; Calculate the bytes to skip once we have read the required bytes. + EX DE,HL + POP HL ; Get the store address into HL. +SD_READ4: PUSH HL ; Start reading bytes into the buffer. + PUSH DE + PUSH BC CALL SPIIN + POP BC + POP DE POP HL LD (HL),A INC HL ; Update buffer pointer. - -SD_READ13: LD BC,(SDBYTECNT) ; Get the count DEC BC - LD (SDBYTECNT),BC ; And decrement, test to see if we have reached zero. LD A,B OR C - JP NZ,SD_READ15 ; Not zero, keep reading. - LD (SDLOADADDR),HL ; Update memory copy of buffer pointer (for reference only). - -SD_READ12: LD BC,(BYTECNT) ; Get the number of bytes we dont want. - CALL SPISKIP ; Skip them to complete the transaction. + JP NZ,SD_READ4 ; Not zero, keep reading. + PUSH HL + PUSH DE + POP BC + INC BC ; Were not interested in the CRC so skip it. + INC BC + CALL SPISKIP ; Skip unread bytes + CRC. + POP HL LD A,0 ; And exit with success. - LD (RESULT),A -SD_READ4: +SD_READ5: PUSH AF LD A,0 CALL SPICS - LD A,(RESULT) + POP AF RET +SD_READ6: POP BC + POP HL + LD A,1 + JR SD_READ5 - ; Method to write a sector or partial sector contents to an SD Card. - ; This method was originally a C routine I was using for FatFS but optimised it (still more can be done). The C->ASM is not so optimal. + ; Method to write a 512byte sector to an SD Card. ; - ; Input: on Stack : Position 2 = unsigned long sector of 4 bytes. - This is the sector number if *buf = NULL, the byte count to write if *buf != NULL, - ; or NULL to initialise/finalise a sector write. - ; Position 6 = unsigned char BYTE *buf of 2 bytes.- This is the pointer to the data for writing. If NULL it indicates an initialise/ - ; finalise action with above sector being use to indicate mode (!= 0 initialise, 0 = finalise). - ; If not NULL points to actual data for writing with the number of bytes stored in sector above. ; Input: Memory variables: SDSTARTSEC= unsigned long sector. - The sector number or direct byte address for older cards. This is big endian as per card. - ; SDLOADADDR= unsigned char BYTE *buf - Pointer to a buffer where the bytes should be stored - ; Output: A = 0 - All ok. A > 0 - error occurred. -SD_WRITE: LD A,1 - LD (RESULT),A + ; HL: Address of buffer to read data from. + ; BC: Size of data to write, upto a sector size. + ; Output: A: 0 - All ok. A > 0 - error occurred. + ; HL: Address of end of buffer. +SD_WRITE: PUSH HL + PUSH BC LD A,0FFH ; Activate CS (set low). CALL SPICS - LD HL,(SDLOADADDR) ; If buffer is not null, we are writing data, otherwise we are instigating a write transaction. - LD A,H - OR L - JP Z,SD_WRITE3 ; NULL so we are performing a transaction open/close. - - LD HL,(SDSTARTSEC+2) ; Get the sector into DEHL. - ADD HL,SP - LD A,(HL) - INC HL - LD H,(HL) - LD L,A - LD (BYTECNT),HL ; Only interested in the lower 16bit value of the long. - -SD_WRITE4: LD A,H ; So long as we have bytes in the buffer, send to the card for writing. - OR L - JP Z,SD_WRITE5 - LD HL,(WRITECNT) ; Count of bytes to write. - LD A,H - OR L - JR Z,SD_WRITE5 ; If either the max count (512) or the requested count (BYTECNT) have expired, exit. - - LD HL,(SDLOADADDR) ; Load the buffer pointer. - LD A,(HL) ; Get the byte to transmit. - INC HL ; And update the pointer. - LD (SDLOADADDR),HL - CALL SPIOUT - - LD HL,(WRITECNT) ; Decrement the max count. - DEC HL - LD (WRITECNT),HL - LD HL,(BYTECNT) ; Decrement the requested count. - DEC HL - LD (BYTECNT),HL ; Whichever counter hits 0 first terminates the transmission. - JP SD_WRITE4 - -SD_WRITE5: LD A,0 - LD (RESULT),A - JP SD_WRITE8 - -SD_WRITE3: LD HL,(SDSTARTSEC) ; Get the sector number into DEHL to test if 0. Dont worry about endian as we are testing for 0. - LD DE,(SDSTARTSEC+2) - LD A,H - OR L - OR D - OR E - JP Z,SD_WRITE9 ; Sector is 0 so finalise the write transaction. - + ; Open transaction. LD HL,(SDCAP) ; Check to see if the card has block addressing. LD H,0 LD A,CT_BLOCK AND L - JP NZ,SD_WRITE10 ; If it hasnt then we need to multiply up to the correct byte. + JP NZ,SD_WRITE1 ; If it hasnt then we need to multiply up to the correct byte. CALL LBATOADDR ; Multiply the sector by 512 for byte addressing. ; A = ACMD to send ; LHED = Argument, ie. ACMD = A, L, H, E, D, CRC -SD_WRITE10: LD A,CMD24 ; Send CMD24 to write a sector. +SD_WRITE1: LD A,CMD24 ; Send CMD24 to write a sector. LD (SDBUF),A LD HL,(SDSTARTSEC) ; Place long endian sector into command buffer. LD (SDBUF+1),HL @@ -644,80 +637,85 @@ SD_WRITE10: LD A,CMD24 ; Send CALL SDCMDNP ; Send command using No Parameters version as we loaded them into the command buffer already. LD A,(SDBUF+6) ; Fetch result and store. AND A - JP NZ,SD_WRITE8 + JP NZ,SD_WRITE10 LD A,255 ; Ok, so command sent successfully, mark the write by sending an 0xFF followed by 0xFE CALL SPIOUT LD A,254 CALL SPIOUT - LD HL,SD_SECSIZE ; Full sector write. - LD (WRITECNT),HL - LD A,0 ; Assume success unless directed otherwise. - LD (RESULT),A - JP SD_WRITE8 -SD_WRITE9: LD HL,(WRITECNT) ; Add 2 to the remaining padding bytes to account for CRC even though we dont use it. - INC HL - INC HL - LD (BYTECNT),HL -SD_WRITE13: LD HL,(BYTECNT) ; Decrement by 1 to account for byte being sent. - DEC HL - LD (BYTECNT),HL - INC HL - LD A,H ; Test to see if we are already at zero, ie. all bytes sent. Exit if so. - OR L - JP Z,SD_WRITE14 + ; Write buffer. + POP BC + LD HL,SD_SECSIZE + OR A + SBC HL,BC ; Calculate number of bytes to pad with 0. + EX DE,HL + POP HL ; Address to read data from. + ; +SD_WRITE2: LD A,B ; So long as we have bytes in the buffer, send to the card for writing. + OR C + JP Z,SD_WRITE3 + + PUSH DE + PUSH BC + LD A,(HL) ; Get the byte to transmit. + INC HL ; And update the pointer. + CALL SPIOUT ; Transmit value in A. + POP BC + POP DE + DEC BC + JR SD_WRITE2 + + ; Close transaction. +SD_WRITE3: PUSH HL ; Save the end of buffer address for return to caller. + PUSH DE ; DE contains number of padding bytes to send + POP BC + INC BC ; Add 2 bytes for CRC + INC BC +SD_WRITE4: LD A,B ; Test to see if we are already at zero, ie. all bytes sent. Exit if so. + OR C + JP Z,SD_WRITE5 + DEC BC + PUSH BC LD A,0 ; Send 0's as padding bytes and CRC. CALL SPIOUT - JP SD_WRITE13 -SD_WRITE14: CALL SPIIN ; Check received response, if 0x05 which indicates write under way inside SD Card. + POP BC + JP SD_WRITE4 + +SD_WRITE5: CALL SPIIN ; Check received response, if 0x05 which indicates write under way inside SD Card. AND 01FH - LD L,A - LD H,0 CP 5 - JP NZ,SD_WRITE15 + JP NZ,SD_WRITE11 LD HL,10000 ; Now wait for the write to complete allowing 1000mS before timing out. PUSH HL - JR SD_WRITE18 -SD_WRITE20: DEC HL + JR SD_WRITE7 +SD_WRITE6: DEC HL PUSH HL LD HL,200 ; 200T state delay = 200 x 1/2000000 = 100uS CALL T_DELAY -SD_WRITE18: CALL SPIIN ; Get a byte, if it is not 0xFF then we have our response so exit. +SD_WRITE7: CALL SPIIN ; Get a byte, if it is not 0xFF then we have our response so exit. POP HL CP 255 - JP Z,SD_WRITE17 + JP Z,SD_WRITE8 LD A,H OR L - JR NZ,SD_WRITE20 + JR NZ,SD_WRITE6 -SD_WRITE17: LD A,H ; End of timeout? If so we exit with the preset fail code. +SD_WRITE8: LD A,H ; End of timeout? If so we exit with the preset fail code. OR L - JP Z,SD_WRITE15 - LD A,0 ; Change to success code as all was ok. - LD (RESULT),HL -SD_WRITE15: LD A,000H ; Disable SD Card Chip Select to finish. + JP Z,SD_WRITE11 + XOR A ; Success code. + POP HL ; Get the updated return address to pass back to caller. +SD_WRITE9: PUSH AF + LD A,000H ; Disable SD Card Chip Select to finish. CALL SPICS -SD_WRITE8: LD A,(RESULT) ; Return result. + POP AF RET +SD_WRITE10: POP HL ; Waste the byte count and .. +SD_WRITE11: POP HL ; ..load address. + LD A,1 ; Error exit. + JR SD_WRITE9 - ; Method to print out the filename within an MZF header or SD Card header. - ; The name may not be terminated as the full 17 chars are used, so this needs - ; to be checked. - ; Input: DE = Address of filename. - ; -PRTFN: PUSH BC - LD B,FNSIZE ; Maximum size of filename. -PRTMSG: LD A,(DE) - INC DE - CP 000H ; If there is a valid terminator, exit. - JR Z,PRTMSGE - CP 00DH - JR Z,PRTMSGE - CALL PRNT - DJNZ PRTMSG ; Else print until 17 chars have been processed. -PRTMSGE: POP BC - RET ; Method to print out an SDC directory entry name along with an incremental file number. The file number can be ; used as a quick reference to a file rather than the filename. @@ -756,7 +754,9 @@ PRTNOWAIT: LD A,E CALL PRNT POP DE PUSH DE ; Get pointer to the file name and print. - CALL PRTFN ; Print out the filename. + + LD HL,PRTFN + CALL BKSW2to6 ; Print out the filename. ; LD HL, (DSPXY) ; @@ -817,13 +817,13 @@ GETSDDIRENT:PUSH BC LD (SDLOADADDR),HL LD HL,0 LD (SDSTARTSEC),HL - LD (SDOFFSET),HL LD B,C LD C,0 LD (SDSTARTSEC+2),BC LD HL,SD_SECSIZE LD (SDLOADSIZE),HL - LD (SDBYTECNT),HL + LD HL,(SDLOADADDR) + LD BC,SD_SECSIZE ; DI CALL SD_READ ; Read the sector. @@ -831,6 +831,7 @@ GETSDDIRENT:PUSH BC ; OR A JR NZ,DIRSDERR + LD (SDLOADADDR),HL ; Save the updated address. GETDIRSD0: POP DE PUSH DE LD A,E ; Retrieve the directory entry number required. @@ -848,15 +849,68 @@ GETDIRSD3: OR A RET ; DIRSDERR: EX DE,HL ; Print error message, show HL as it contains sector number where error occurred. + PUSH HL + POP BC ; HL to BC as the call requires the value to be displayed in BC. LD DE,MSGSDRERR - RST 018H - CALL PRTHL - CALL NL + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. POP DE POP BC LD A,1 JR GETDIRSD3 + ; Method to find a free slot in the directory. + ; + ; Input: None. + ; Output: E = Free directory entry. + ; HL = Address of directory entry. + ; C = 1 if no free directory slot available. + ; Unless other directory entry functions called, DIRSECBUF = directory sector in cache which contains the free entry found. +GETDIRFREE: LD A,0FFH + LD (DIRSECBUF),A ; Reset the sector buffer in memory indicator. + ; + LD E,0 ; Directory entry number + LD B,0 ; Scanning 256 directory entries for a free slot. +GETDIRFREE1:CALL GETSDDIRENT ; Get SD Directory entry details for directory entry number stored in D. + RET NZ ; Error reading sector so abort. + LD A,(HL) + BIT 7,A ; Look for an inactive directory entry slot, Bit 7 of lower flag = 0? + JR NZ,GETDIRFREE2 + OR A + RET ; Found an entry that is free. +GETDIRFREE2:INC E ; Onto next directory entry number. + DJNZ GETDIRFREE1 + SCF + RET + + + ; Method to write the cached SD Directory entry sector back to SD card. + ; Normal use would be to call GERSDDIRENT to locate a required entry or slot, update it then call + ; this method to flush it back to SD disk. +WRSDDIRENT: LD A,(DIRSECBUF) ; Get the directory sector number of the cached directory sector. + LD B,A + LD C,0 + LD (SDSTARTSEC+2),BC ; Set the sector ready to perform the write. + LD HL,SECTORBUF ; Address of the sector. + LD BC,SD_SECSIZE ; Set the size as one full sector. + ; + DI + CALL SD_WRITE + EI + ; + OR A + JR NZ,DIRSDWERR + LD A,0 +WRSDDIRENT1:OR A + RET +DIRSDWERR: LD DE,MSGSDWERR + PUSH HL + POP BC ; HL to BC as the call requires the value to be displayed in BC. + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. + LD A,1 + JR WRSDDIRENT1 + ; Method to list the directory of the SD Card. @@ -873,8 +927,8 @@ DIRSDCARD: LD A,1 ; Setup LD (DIRSECBUF),A ; Reset the sector buffer in memory indicator. ; LD DE,MSGCDIRLST ; Print out header. - RST 018h - CALL NL + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. ; DIRSD0: LD E,0 ; Directory entry number LD D,0 ; Directory file number (incr when a valid dirent is found). @@ -894,23 +948,36 @@ DIRSD3: INC E ; Onto DIRSD4: RET ; - ; Load a program from the SD Card into RAM and/or execute it - Part 2. - ; - ; DE contains start position of given filename. If TMPCNT contains a non 0FFFFH number then - ; DE points to a file number which will be used for matching. - ; -LOADSDE: PUSH DE + + ; Method to locate an entry in the SD directory based on a filenumber or a filename. + ; This method is called with the raw parameter string in DE which is then parsed to determine if a filenumber + ; or filename has been given. + ; Input: DE = String containing a filenumber of filename. + ; Output: (TMPCNT) = 0xFFFF - DE contains a filename. + ; (TMPCNT) != 0xFFFF - DE contains a filenumber and (TMPCNT) is set to that number. +FINDSDX: PUSH DE + LD HL,0FFFFh ; Tag the filenumber as invalid. + LD (TMPCNT), HL + CALL _2HEX + JR C, FINDSDX1 ; + LD L,A + LD H,0 + LD (TMPCNT), HL ; Store filenumber making load by filenumber valid. +FINDSDX1: POP DE + + ; Method to locate an entry in the SD directory based on a filenumber or a filename. + ; Input: DE = String containing a filenumber or filename. + ; (TMPCNT) = 0xFFFF - DE contains a filename. + ; (TMPCNT) != 0xFFFF - Filenumber. +FINDSD: PUSH DE LD A,0FFH LD (DIRSECBUF),A ; Reset the sector buffer in memory indicator. LD E,0 ; Directory entry number start LD D,0 ; Directory file number (incr when a valid dirent is found). LD B,0 -LOADSD1: CALL GETSDDIRENT ; Get SD Directory entry details for directory entry number stored in D. -LOADSD2: LD A,(HL) - INC HL - INC HL ; Hop over flags. - BIT 7,A ; Is this entry active, ie. Bit 7 of lower flag = 1? - JR Z,LOADSD3 +FINDSD1: CALL GETSDDIRENT ; Get SD Directory entry details for directory entry number stored in D. +FINDSD2: BIT 7,(HL) ; Is this entry active, ie. Bit 7 of lower flag = 1? + JR Z,FINDSD3 PUSH HL LD HL,(TMPCNT) LD H,(HL) @@ -918,48 +985,106 @@ LOADSD2: LD A,(HL) CP 0FFH LD A,L POP HL - JR Z,LOADSD4 ; A filenumber wasnt given so will need to name match. + JR Z,FINDSD4 ; A filenumber wasnt given so will need to name match. CP D ; Match on filenumber, does the given number match with the current? - JR Z,LOADSD9 + JR Z,FINDSD9 INC D -LOADSD3: INC E - DJNZ LOADSD1 +FINDSD3: INC E + DJNZ FINDSD1 POP DE LD A,1 - JP LOADSDX1 ; We didnt find a match so exit with code 1. + JP FINDSD10 ; We didnt find a match so exit with code 1. -LOADSD4: POP DE ; Get back pointer to given filename. HL contains directory filename. +FINDSD4: POP DE ; Get back pointer to given filename. HL contains directory filename. PUSH DE PUSH BC ; Save BC as we need it for comparison. LD B,SDDIR_FNSZ -LOADSD5: LD A,(HL) - LD (DE),A - CP 00Dh ; If we find a terminator then this indicates potentially a valid name. - JR Z, LOADSD7 - CP 020h ; >= Space - JR C, LOADSD8 - CP 05Dh ; =< ] - JR C, LOADSD6 - CP 091h - JR C, LOADSD8 ; DEL or > 0x7F, cant be a valid filename so this is not an MZF header. -LOADSD6: INC DE INC HL - DJNZ LOADSD5 - JR LOADSD8 ; No end of string terminator, this cant be a valid filename. -LOADSD7: LD A,B + INC HL ; Hop over flags. +FINDSD5: LD A,(HL) + LD (DE),A + CP 00Dh ; If we find a terminator then this is a valid name. + JR Z, FINDSD9A + CP 020h ; >= Space + JR C, FINDSD8 + CP 05Dh ; =< ] + JR C, FINDSD6 + CP 091h + JR C, FINDSD8 ; DEL or > 0x7F, cant be a valid filename so this is not an MZF header. +FINDSD6: INC DE + INC HL + DJNZ FINDSD5 +FINDSD7: LD A,B CP SDDIR_FNSZ - JR NZ,LOADSD9 ; If the filename has no length it cant be valid, so loop. -LOADSD8: POP BC ; No match on filename so go back for next directory entry. + JR Z,FINDSD9 ; If we matched all FNSIZE characters then this is a valid name. +FINDSD8: POP BC ; No match on filename so go back for next directory entry. POP DE - JR LOADSD3 + JR FINDSD3 +FINDSD9A: POP BC +FINDSD9: POP BC ; Waste the pointer to the input string. + LD A,0 ; D contains the filenumber. +FINDSD10: OR A + RET + + + ; Method to erase a file in the SD RFS. This is a simple matter of resetting the valid entry flag (bit 7 of FLAG1) in the directory entry for + ; the required file. + ; Input: DE = String containing filenumber or filename to erase. + ; Output: A = 0 Success, 1 = Fail. +ERASESD: CALL FINDSDX + JR NZ,LOADSD3 ; Not found? Print message and exit. + ; Directory entry in cache, HL points to FLAG1 of entry. + LD A,(HL) ; Clear the valid entry flag, bit 7 of FLAG1 + AND 07FH + LD (HL),A + PUSH DE + CALL WRSDDIRENT ; Flush the directory entry to disk to effect the delete. + OR A + JR NZ,ERASESD1 ; Failure, the report and exit. + POP BC ; Get the directory entry number. + LD B,0 + LD DE,MSGERASEDIR + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. + LD A,0 ; Success. + RET +ERASESD1: LD DE,MSGERAFAIL ; Fail, print out message. + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. + LD A,1 + RET + + + ; Entry point when copying the SD file. Setup flags to indicate copying to effect any special processing. + ; The idea is to load the file into memory, dont execute and pass back the parameters within the CMT header. + ; +LOADSDCP: LD A,0FFH + LD (SDAUTOEXEC),A + JR LOADSD2 + + ; Load a program from the SD Card into RAM and/or execute it. + ; + ; DE points to a number or filename to load. +LOADSDCARDX:LD A,0FFH + JR LOADSD1 +LOADSDCARD: LD A,000H +LOADSD1: LD (SDAUTOEXEC),A + XOR A ; Clear copying flag. +LOADSD2: LD (SDCOPY),A + LD A,0FFH ; For interbank calls, save result in a memory variable. + LD (RESULT),A + CALL FINDSDX + JR Z,LOADSD9 +LOADSD3: LD DE,MSGNOTFND + LD HL,PRINTMSG + CALL BKSW2to6 ; Print message that file wasnt found. + RET ; We have found the directory entry, so use it to load the program into memory. ; HL points to end of filename so requires an update to point to start of the directory entry. -LOADSD9: POP DE ; No longer need buffer pointer so waste. - ; Copy all relevant information into the CMT header (for reference) and working variables. ; - LD A,L +LOADSD9: LD A,L AND 0E0H INC A LD L,A @@ -978,7 +1103,6 @@ LOADSD9: POP DE ; No lo INC HL LD D,(HL) ; Start sector lower 16 bits, big endian. INC HL - LD (COMNT),DE LD (SDSTARTSEC+2),DE LD E,(HL) INC HL @@ -991,7 +1115,8 @@ LOADSD9: POP DE ; No lo LD D,(HL) ; Load address. INC HL LD A,D - CP 001H + LD (DTADRSTORE),DE ; Save the original load address, use this to fill DTADR when complete if it has changed.. + CP 001H JR NC,LOADSD10 LD DE,01200H ; If the file specifies a load address below 1000H then shift to 1200H as it is not valid. LOADSD10: LD (DTADR),DE @@ -1000,26 +1125,24 @@ LOADSD10: LD (DTADR),DE INC HL LD D,(HL) ; Execution address, store in tape header memory. LD (EXADR),DE - LD DE,0 - LD (SDOFFSET),DE ; - LD DE,MSGSDLOAD - RST 018H - LD DE,NAME - CALL PRTFN - CALL NL + LD DE,MSGLOAD+1 ; Skip initial CR. + LD BC,NAME + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. ; LOADSD11: LD A,(SDLOADSIZE+1) CP 002H - LD HL,SD_SECSIZE ; A full sector read if remaining bytes >=512 + LD BC,SD_SECSIZE ; A full sector read if remaining bytes >=512 JR NC,LOADSD12 - LD HL,(SDLOADSIZE) ; Get remaining bytes size. -LOADSD12: LD (SDBYTECNT),HL + LD BC,(SDLOADSIZE) ; Get remaining bytes size. +LOADSD12: LD HL,(SDLOADADDR) DI CALL SD_READ ; Read the sector. EI OR A - JR NZ,LOADSDERR ; Failure to read a sector, abandon with error message. + JP NZ,LOADSDERR ; Failure to read a sector, abandon with error message. + LD (SDLOADADDR),HL ; Save the updated address. ; LD HL,SDSTARTSEC+3 INC (HL) @@ -1040,91 +1163,193 @@ LOADSD14: LD A,(SDAUTOEXEC) ; Autoe CP 0FFh JP Z,LOADSD15 ; Go back to monitor if it has been, else execute. LD A,(ATRB) - CP 1 + CP OBJCD JR NZ,LOADSD17 LD HL,(EXADR) JP (HL) ; Execution address. -LOADSD15: LD DE,MSGEXECADDR ; Indicate where the program was loaded and the execution address. -LOADSD16: RST 018H - LD HL,(EXADR) - CALL PRTHL - LD DE,MSGLOADADDR - RST 018H +LOADSD15: LD DE,MSGCMTDATA ; Indicate where the program was loaded and the execution address. LD HL,(DTADR) - CALL PRTHL - CALL NL - JR LOADSDX -LOADSD17: LD DE,MSGNOTBIN - JR LOADSD16 + PUSH HL + LD HL,(EXADR) + PUSH HL + LD BC,(SIZE) +LOADSD16: LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. + POP BC + POP BC ; Remove parameters off stack. LOADSDX: LD A,0 ; Non error exit. -LOADSDX1: RET +LOADSDX1: LD (RESULT),A + RET +LOADSD17: LD DE,MSGNOTBIN + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. + JR LOADSD16 LOADSDERR: LD DE,MSGSDRERR - RST 018H - LD HL,(TMPCNT) - CALL PRTHL - CALL NL + LD HL,PRINTMSG + LD BC,(TMPCNT) + CALL BKSW2to6 ; Print out the filename. LD A,2 JR LOADSDX1 + ; Setup for saving an application to SD Card but using the CMT header. Also set the copy flag because the values in the header + ; may not reflect where the image is stored (ie. CTM LOAD=0x0000 -> data is at 0x1200). + ; +SAVESDCARDX:LD A,0FFH + JR SAVESD1 + ; Method to save a block of memory to the SD card as a program. ; The parameters which should be given are: ; XXXXYYYYZZZZ - where XXXX = Start Address, YYYY = End Address, ZZZZ = Execution Address. - ; Prompt for a filename which will be written into the SD Card directory. + ; Prompt for a filename which will be written into the CMT header. + ; All the values are stored in the CMT header and copied as needed into the SD directory. ; -SAVESDCARD: CALL READHEX ; Start address - LD (DTADR),HL ; data adress buffer - LD B,H - LD C,L - CALL INCDE4 - CALL READHEX ; End address - SBC HL,BC ; byte size +SAVESDCARD: LD HL,GETCMTPARM ; Get the CMT parameters. + CALL BKSW2to3 + LD A,C + OR A + RET NZ ; Exit if an error occurred. + + XOR A ; Disable the copy flag. +SAVESD1: LD (SDCOPY),A + LD A,0FFH ; Interbank calls, pass result via a memory variable. Assume failure unless updated. + LD (RESULT),A + LD A,OBJCD ; Set attribute: OBJ + LD (ATRB),A + + ; Find free slot. + CALL GETDIRFREE + JR NC,SAVESD4 + LD DE,MSGDIRFULL ; Directory is full so abort command. + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. + LD A,1 ; Directory full code. + LD (RESULT),A + RET + ; +SAVESD4: PUSH DE ; Save the directory entry number. + PUSH HL + LD B,0 + LD C,E + LD DE,MSGSVDIRENT + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. + POP HL + LD A,080H + LD (HL),A ; Set directory entry flag indicating that the entry is in use. INC HL - LD (SIZE),HL ; byte size buffer - CALL INCDE4 - CALL READHEX ; execute address - LD (EXADR),HL ; buffer - CALL NL - LD DE,MSGSAVESD ; 'FILENAME? ' - RST 018h - CALL GETLHEX ; filename input - CALL INCDE4 - CALL INCDE4 - LD HL,NAME ; name buffer -SAVESD1: INC DE - LD A,(DE) - LD (HL),A ; filename trans. + LD A,(ATRB) + LD (HL),A ; Copy attribute. INC HL - CP 00Dh ; end code - JR NZ,SAVESD1 + LD BC,SDDIR_FNSZ + LD DE,NAME + EX DE,HL + LDIR ; Copy filename across to directory. + EX DE,HL + POP DE ; Get directory entry number in E. + ; + PUSH HL + LD D,0 + LD BC,SDDIR_BLOCKSZ / SD_SECSIZE ; Put the blocksize as sectors into BC and multiply with E to get the block address. + CALL MULT16X16 ; DEHL to contain LBA address for given block. + LD BC,SDDIR_DIRSIZE / SD_SECSIZE + CALL ADD3216 ; Add in size of directory to arrive at correct LBA sector. + PUSH HL + POP BC ; 32bit LBA now in DEBC + POP HL + LD (HL),D ; Now save the 32bit LBA sector number into the directory entry. + LD (SDSTARTSEC),DE ; DE will always be 0 for RFS so we dont worry about endian, ie. (256 * 64K + 256 * 32)/512 = 0x00008010 + INC HL + LD (HL),E + INC HL + LD A,B + LD (HL),A + LD (SDSTARTSEC+2),A + INC HL + LD A,C + LD (HL),A + LD (SDSTARTSEC+3),A + INC HL + ; + LD DE,(SIZE) ; Add in the size of the program. + LD (SDLOADSIZE),DE + LD (HL),E + INC HL + LD (HL),D + INC HL + ; + LD DE,(DTADR) ; Add in the load address of the program. + LD (HL),E + INC HL + LD (HL),D + INC HL + ; + LD A,(SDCOPY) + OR A + JR Z,SAVEDS4A + LD DE,01200H ; Copy mode -> data is always at 0x1200. +SAVEDS4A: LD (SDLOADADDR),DE + ; + LD DE,(EXADR) ; Add in the execution address of the program. + LD (HL),E + INC HL + LD (HL),D + INC HL + ; + ; Header has been written into the cached directory sector, write out data and if successful, write out + ; the directory entry to complete. + ; +SAVESD5: LD A,(SDLOADSIZE+1) + CP 002H + LD BC,SD_SECSIZE ; A full sector read if remaining bytes >=512 + JR NC,SAVESD6 + LD BC,(SDLOADSIZE) ; Get remaining bytes size. +SAVESD6: LD HL,(SDLOADADDR) + DI + CALL SD_WRITE ; Write the sector. + EI + OR A + JR NZ,SAVESD9 ; Failure to read a sector, abandon with error message. + LD (SDLOADADDR),HL ; Save the updated address. + ; + LD HL,SDSTARTSEC+3 + INC (HL) + JR NZ,SAVESD7 + DEC HL + INC (HL) +SAVESD7: LD A,(SDLOADSIZE+1) + CP 002H + JR C,SAVESD8 ; If carry then the last read obtained the remaining bytes. + LD HL,(SDLOADSIZE) + LD DE,SD_SECSIZE + OR A + SBC HL,DE + LD (SDLOADSIZE),HL + JR SAVESD5 +SAVESD8: ; Data written, now write out the directory entry. + CALL WRSDDIRENT ; Flush the directory entry to disk. + ;PUSH HL + ;PUSH DE + ;PUSH BC + ;LD BC,01000H + ;LD DE,0D000H + ;LD HL,DUMPBC + ;CALL BKSW2to3 + ;POP BC + ;POP DE + ;POP HL + OR A + JR NZ,SAVESD9 + LD A,0 ; Success. + LD (RESULT),A + RET +SAVESD9: LD DE,MSGSVFAIL ; Fail, print out message. + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. + LD A,1 ; Write failed code. + LD (RESULT),A RET - ; Method to read 4 hex digits and convert to a 16bit number. - ; -READHEX: EX (SP),IY - POP AF - CALL HLHEX - JR C,READHEX2 ; Exit if the input is invalid - JP (IY) -READHEX2: POP AF ; Waste the intermediate caller address - RET - - ; Add 4 to DE. -INCDE4: INC DE - INC DE - INC DE - INC DE - RET - - ; Read a line from the user and store in BUFER. -READLHEX: EX (SP),HL ; Get return address into HL and pop of old HL value into BC. - POP BC - LD DE,BUFER - CALL GETL ; Input a line from the user. - LD A,(DE) ; Escape? Return to command processor. - CP 01Bh - JR Z,READHEX2 - JP (HL) ; Else go to original return address. ;------------------------------------------------------------------------------- ; END OF SD CONTROLLER FUNCTIONALITY ;------------------------------------------------------------------------------- @@ -1132,16 +1357,9 @@ READLHEX: EX (SP),HL ; Get r ;-------------------------------------- ; - ; Message table + ; Message table - Refer to Bank 6 for + ; messages. ; ;-------------------------------------- -MSGCDIRLST: DB "SDCARD DIRECTORY:", 00DH -MSGSDRERR: DB "SDCARD READ ERROR, SECTOR:", 00DH -MSGLOADADDR:DB ", LOAD ADDR:", 00DH -MSGEXECADDR:DB "EXEC ADDR:", 00DH -MSGNOTBIN: DB "NOT BINARY", 00DH -MSGSDLOAD: DB "LOADING ", 00DH -MSGSAVESD: DB "FILENAME: ", 00DH - ALIGN 0EFFFh DB 0FFh diff --git a/software/asm/rfs_bank3.asm b/software/asm/rfs_bank3.asm index cbb56a1..4de4e82 100644 --- a/software/asm/rfs_bank3.asm +++ b/software/asm/rfs_bank3.asm @@ -34,7 +34,7 @@ MODE80C EQU 0 ;=========================================================== ; - ; USER ROM BANK 3 - Monitor memory and help utilities. + ; USER ROM BANK 3 - Monitor memory utilities. ; ;=========================================================== ORG UROMADDR @@ -92,48 +92,110 @@ BKSW3to7: PUSH AF PUSH AF LD A, ROMBANK7 ; Required bank to call. ; -BKSW3_0: PUSH BC ; Save BC for caller. - LD BC, BKSWRET3 ; Place bank switchers return address on stack. - PUSH BC - LD (RFSBK2), A ; Bank switch in user rom space, A=bank. +BKSW3_0: PUSH HL ; Place function to call on stack + LD HL, BKSWRET3 ; Place bank switchers return address on stack. + EX (SP),HL LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it. + LD (RFSBK2), A ; Bank switch in user rom space, A=bank. JP (HL) ; Jump to required function. -BKSWRET3: POP BC - POP AF ; Get bank which called us. +BKSWRET3: POP AF ; Get bank which called us. LD (RFSBK2), A ; Return to that bank. POP AF RET ; Return to caller. - ;------------------------------------------------------------------------------- - ; START OF MEMORY CMDLINE TOOLS FUNCTIONALITY - ;------------------------------------------------------------------------------- + ;------------------------------------------------------------------------------- + ; START OF TAPE/SD CMDLINE TOOLS FUNCTIONALITY + ;------------------------------------------------------------------------------- -; -; Memory correction -; command 'M' -; -MCORX: CALL GETHEX ; correction address + ; Method to copy an application on a tape to an SD stored application. The tape drive is read and the first + ; encountered program is loaded into memory at 0x1200. The CMT header is populated with the correct details (even if + ; the load address isnt 0x1200, the CMT Header contains the correct value). + ; A call is then made to write the application to the SD card. + ; +TAPE2SD: ; Load from tape into memory, filling the tape CMT header and loading data into location 0x1200. + LD HL,LOADTAPECP ; Call the Loadtape command, non execute version to get the tape contents into memory. + CALL BKSW3to4 + LD A,(RESULT) + OR A + JR NZ,TAPE2SDERR + ; Save to SD Card. + LD HL,SAVESDCARDX + CALL BKSW3to2 + LD A,(RESULT) + OR A + JR NZ,TAPE2SDERR + LD DE,MSGT2SDOK + JR TAPE2SDERR2 +TAPE2SDERR: LD DE,MSGT2SDERR +TAPE2SDERR2:LD HL,PRINTMSG + CALL BKSW3to6 + RET + + ; Method to copy an SD stored application to a Cassette tape in the CMT. + ; The directory entry number or filename is passed to the command and the entry is located within the SD + ; directory structure. The file is then loaded into memory and the CMT header populated. A call is then made + ; to write out the data to tap. + ; +SD2TAPE: ; Load from SD, fill the CMT header then call CMT save. + LD HL,LOADSDCP + CALL BKSW3to2 + LD A,(RESULT) + OR A + JR NZ,SD2TAPEERR + LD HL,SAVECMT + CALL BKSW3to4 + LD A,(RESULT) + OR A + JR NZ,SD2TAPEERR + RET +SD2TAPEERR: LD DE,MSGSD2TERR + JR TAPE2SDERR2 + RET + ;------------------------------------------------------------------------------- + ; END OF TAPE/SD CMDLINE TOOLS FUNCTIONALITY + ;------------------------------------------------------------------------------- + + + ;------------------------------------------------------------------------------- + ; START OF MEMORY CMDLINE TOOLS FUNCTIONALITY + ;------------------------------------------------------------------------------- + + ; + ; Memory correction + ; command 'M' + ; +MCORX: CALL READ4HEX ; correction address + RET C MCORX1: CALL NLPHL ; corr. adr. print CALL SPHEX ; ACC ASCII display CALL PRNTS ; space print - CALL BGETLX ; get data & check data - CALL HLHEX ; HLASCII(DE) - JR C,MCRX3 - CALL DOT4DE ; INC DE * 4 - INC DE - CALL _2HEX ; data check - JR C,MCORX1 - CP (HL) - JR NZ,MCORX1 - INC DE + LD DE,BUFER ; Input the data. + CALL GETL LD A,(DE) + CP 01Bh ; If . pressed, exit. + RET Z + PUSH HL + POP BC + CALL HLHEX ; If the existing address is no longer hex, reset. HLASCII(DE). If it is hex, take as the address to store data into. + JR C,MCRX3 ; Line is corrupted as the address is no longer in Hex, reset. + INC DE + INC DE + INC DE + INC DE + INC DE ; + CALL _2HEX ; Get value entered. + JR C,MCORX1 ; Not hex, reset. + CP (HL) ; Not same as memory, reset. + JR NZ,MCORX1 + INC DE ; + LD A,(DE) ; Check if no data just CR, if so, move onto next address. CP 00Dh ; not correction JR Z,MCRX2 - CALL _2HEX ; ACCHL(ASCII) - JR C,MCORX1 - LD (HL),A ; data correct + CALL _2HEX ; Get the new entered data. ACCHL(ASCII) + JR C,MCORX1 ; New data not hex, reset. + LD (HL),A ; data correct so store. MCRX2: INC HL JR MCORX1 MCRX3: LD H,B ; memory address @@ -141,17 +203,52 @@ MCRX3: LD H,B ; memor JR MCORX1 -DUMPX: CALL GETHEX - CALL DOT4DE + ; Dump method when called interbank as HL cannot be passed. + ; + ; BC = Start + ; DE = End +DUMPBC: PUSH BC + POP HL + JR DUMP + + ; Command line utility to dump memory. + ; Get start and optional end addresses from the command line, ie. XXXX[XXXX] + ; Paging is implemented, 23 lines at a time, pressing U goes back 100H, pressing D scrolls down 100H + ; +DUMPX: CALL HLHEX ; Get start address if present into HL + JR NC,DUMPX1 + LD DE,(DUMPADDR) ; Setup default start and end. + JR DUMPX2 +DUMPX1: INC DE + INC DE + INC DE + INC DE PUSH HL - CALL HLHEX - POP DE - JR C,DUM4 -DUM1: EX DE,HL -DUM3: LD B,008h - LD C,017h - CALL NLPHL -DUM2: CALL SPHEX + CALL HLHEX ; Get end address if present into HL + POP DE ; DE = Start address + JR NC,DUMPX4 ; Both present? Then display. +DUMPX2: LD A,(SCRNMODE) + OR A + LD HL,000A0h ; Make up an end address based on 160 bytes from start for 40 column mode. + JR Z,DUMPX3 + LD HL,00140h ; Make up an end address based on 320 bytes from start for 80 column mode. +DUMPX3: ADD HL,DE +DUMPX4: EX DE,HL + ; + ; HL = Start + ; DE = End +DUMP: LD A,23 +DUMP0: LD (TMPCNT),A + LD A,(SCRNMODE) ; Configure output according to screen mode, 40/80 chars. + OR A + JR NZ,DUMP1 + LD B,008H ; 40 Char, output 23 lines of 40 char. + LD C,017H + JR DUMP2 +DUMP1: LD B,010h ; 80 Char, output 23 lines of 80 char. + LD C,02Fh +DUMP2: CALL NLPHL +DUMP3: CALL SPHEX INC HL PUSH AF LD A,(DSPXY) @@ -159,9 +256,9 @@ DUM2: CALL SPHEX LD (DSPXY),A POP AF CP 020h - JR NC,L0D51 + JR NC,DUMP4 LD A,02Eh -L0D51: CALL ?ADCN +DUMP4: CALL ?ADCN CALL PRNT3 LD A,(DSPXY) INC C @@ -173,32 +270,49 @@ L0D51: CALL ?ADCN PUSH HL SBC HL,DE POP HL - JR Z,L0D85 - LD A,0F8h - LD (0E000h),A - NOP - LD A,(0E001h) - CP 0FEh - JR NZ,L0D78 - CALL ?BLNK -L0D78: DJNZ DUM2 -L0D7A: CALL ?KEY + JR NC,DUMP9 +DUMP5: DJNZ DUMP3 + LD A,(TMPCNT) + DEC A + JR NZ,DUMP0 +DUMP6: CALL GETKY ; Pause, X to quit, D to go down a block, U to go up a block. OR A - JR Z,L0D7A - CALL BRKEY - JP NZ,DUM3 -L0D85: RET ; JR LEA76 -DUM4: LD HL,000A0h - ADD HL,DE - JR DUM1 + JR Z,DUMP6 + CP 'D' + JR NZ,DUMP7 + LD A,8 + JR DUMP0 +DUMP7: CP 'U' + JR NZ,DUMP8 + PUSH DE + LD DE,00100H + OR A + SBC HL,DE + POP DE + LD A,8 + JR DUMP0 +DUMP8: CP 'X' + JR Z,DUMP9 + JR DUMP +DUMP9: LD (DUMPADDR),HL ; Store last address so we can just press D for next page, + CALL NL + RET - ; Clear memory. -INITMEMX: LD DE,MSG_INITM - CALL MSG - CALL LETNL + + ; Cmd tool to clear memory. + ; Read cmd line for an init byte, if one not present, use 00H + ; +INITMEMX: CALL _2HEX + JR NC,INITMEMX1 + LD A,000H +INITMEMX1: PUSH AF + LD DE,MSGINITM + LD HL,PRINTMSG + CALL BKSW1to6 LD HL,1200h LD BC,0D000h - 1200h -CLEAR1: LD A,00h + POP DE +CLEAR1: LD A,D LD (HL),A INC HL DEC BC @@ -207,79 +321,107 @@ CLEAR1: LD A,00h JP NZ,CLEAR1 RET -BGETLX: EX (SP),HL - POP BC + + ; Method to get the CMT parameters from the command line. + ; The parameters which should be given are: + ; XXXXYYYYZZZZ - where XXXX = Start Address, YYYY = End Address, ZZZZ = Execution Address. + ; If the start, end and execution address parameters are correct, prompt for a filename which will be written into the CMT header. + ; Output: Reg C = 0 - Success + ; = 1 - Error. +GETCMTPARM: CALL READ4HEX ; Start address + JR C,GETCMT1 + LD (DTADR),HL ; data adress buffer + LD B,H + LD C,L + CALL READ4HEX ; End address + JR C,GETCMT1 + LD (SIZE),HL ; byte size buffer + CALL READ4HEX ; Execution address + JR C,GETCMT1 + LD (EXADR),HL ; buffer + CALL NL + LD DE,MSGSAVE ; 'FILENAME? ' + LD HL,PRINTMSG + CALL BKSW2to6 ; Print out the filename. LD DE,BUFER CALL GETL - LD A,(DE) - CP 01Bh - JP Z,GETHEX2 - JP (HL) - -GETHEX: EX (SP),IY - POP AF - CALL HLHEX - JR C,GETHEX2 - JP (IY) -GETHEX2: POP AF ; Waste the intermediate caller address - RET + LD HL,BUFER+10 + LD DE,NAME ; name buffer + LD BC,FNSIZE + LDIR ; C = 0 means success. + RET +GETCMT1: LD C,1 ; C = 1 means an error occured. + RET - ; INCREMENT DE REG. -DOT4DE: INC DE - INC DE - INC DE - INC DE - RET + ; Method to read 4 bytes from a buffer pointed to by DE and attempt to convert to a 16bit number. If it fails, print out an error + ; message and return with C set. + ; + ; Input: DE = Address of digits to conver. + ; Output: HL = 16 bit number. - ; SPACE PRINT AND DISP ACC - ; INPUT:HL=DISP. ADR. -SPHEX: CALL PRNTS ; SPACE PRINT - LD A,(HL) - CALL PRTHX ; DSP OF ACC (ASCII) - LD A,(HL) - RET +READ4HEX: CALL HLHEX + JR C,READ4HEXERR + INC DE + INC DE + INC DE + INC DE + OR A ; Clear carry flag. + RET +READ4HEXERR:LD DE,MSGREAD4HEX ; Load up error message, print and exit. + LD HL,PRINTMSG + CALL BKSW1to6 + SCF + RET - ; NEW LINE AND PRINT HL REG (ASCII) -NLPHL: CALL NL - CALL PRTHL - RET - ;------------------------------------------------------------------------------- - ; END OF MEMORY CMDLINE TOOLS FUNCTIONALITY - ;------------------------------------------------------------------------------- + ; SPACE PRINT AND DISP ACC + ; INPUT:HL=DISP. ADR. +SPHEX: CALL PRNTS ; SPACE PRINT + LD A,(HL) + CALL PRTHX ; DSP OF ACC (ASCII) + LD A,(HL) + RET - ;------------------------------------------------------------------------------- - ; START OF PRINTER CMDLINE TOOLS FUNCTIONALITY - ;------------------------------------------------------------------------------- -PTESTX: LD A,(DE) - CP '&' ; plotter test - JR NZ,PTST1X -PTST0X: INC DE - LD A,(DE) - CP 'L' ; 40 in 1 line - JR Z,.LPTX - CP 'S' ; 80 in 1 line - JR Z,..LPTX - CP 'C' ; Pen change - JR Z,PENX - CP 'G' ; Graph mode - JR Z,PLOTX - CP 'T' ; Test - JR Z,PTRNX + ; NEW LINE AND PRINT HL REG (ASCII) +NLPHL: CALL NL + CALL PRTHL + RET + ;------------------------------------------------------------------------------- + ; END OF MEMORY CMDLINE TOOLS FUNCTIONALITY + ;------------------------------------------------------------------------------- + + ;------------------------------------------------------------------------------- + ; START OF PRINTER CMDLINE TOOLS FUNCTIONALITY + ;------------------------------------------------------------------------------- +PTESTX: LD A,(DE) + CP '&' ; plotter test + JR NZ,PTST1X +PTST0X: INC DE + LD A,(DE) + CP 'L' ; 40 in 1 line + JR Z,.LPTX + CP 'S' ; 80 in 1 line + JR Z,..LPTX + CP 'C' ; Pen change + JR Z,PENX + CP 'G' ; Graph mode + JR Z,PLOTX + CP 'T' ; Test + JR Z,PTRNX ; -PTST1X: CALL PMSGX -ST1X2: RET -.LPTX: LD DE,LLPT ; 01-09-09-0B-0D - JR PTST1X -..LPTX: LD DE,SLPT ; 01-09-09-09-0D - JR PTST1X -PTRNX: LD A,004h ; Test pattern - JR LE999 -PLOTX: LD A,002h ; Graph mode -LE999: CALL LPRNTX - JR PTST0X -PENX: LD A,01Dh ; 1 change code (text mode) - JR LE999 +PTST1X: CALL PMSGX +ST1X2: RET +.LPTX: LD DE,LLPT ; 01-09-09-0B-0D + JR PTST1X +..LPTX: LD DE,SLPT ; 01-09-09-09-0D + JR PTST1X +PTRNX: LD A,004h ; Test pattern + JR LE999 +PLOTX: LD A,002h ; Graph mode +LE999: CALL LPRNTX + JR PTST0X +PENX: LD A,01Dh ; 1 change code (text mode) + JR LE999 ; ; ; 1 char print to $LPT @@ -287,36 +429,36 @@ PENX: LD A,01Dh ; 1 cha ; in: ACC print data ; ; -LPRNTX: LD C,000h ; RDAX test - LD B,A ; print data store - CALL RDAX - LD A,B - OUT (0FFh),A ; data out - LD A,080h ; RDP high - OUT (0FEh),A - LD C,001h ; RDA test - CALL RDAX - XOR A ; RDP low - OUT (0FEh),A - RET +LPRNTX: LD C,000h ; RDAX test + LD B,A ; print data store + CALL RDAX + LD A,B + OUT (0FFh),A ; data out + LD A,080h ; RDP high + OUT (0FEh),A + LD C,001h ; RDA test + CALL RDAX + XOR A ; RDP low + OUT (0FEh),A + RET ; ; $LPT msg. ; in: DE data low address ; 0D msg. end ; -PMSGX: PUSH DE - PUSH BC - PUSH AF -PMSGX1: LD A,(DE) ; ACC = data - CALL LPRNTX - LD A,(DE) - INC DE - CP 00Dh ; end ? - JR NZ,PMSGX1 - POP AF - POP BC - POP DE - RET +PMSGX: PUSH DE + PUSH BC + PUSH AF +PMSGX1: LD A,(DE) ; ACC = data + CALL LPRNTX + LD A,(DE) + INC DE + CP 00Dh ; end ? + JR NZ,PMSGX1 + POP AF + POP BC + POP DE + RET ; ; RDA check @@ -351,86 +493,13 @@ SLPT: DB 01H ; TEXT ; END OF PRINTER CMDLINE TOOLS FUNCTIONALITY ;------------------------------------------------------------------------------- - ;------------------------------------------------------------------------------- - ; START OF HELP SCREEN FUNCTIONALITY - ;------------------------------------------------------------------------------- - - ; Simple help screen to display commands. -HELP: CALL NL - LD DE, HELPSCR - CALL PRTSTR - RET - - ; Modification of original MSG function, use NULL terminated strings not CR terminated and include page pause. -PRTSTR: PUSH AF - PUSH BC - PUSH DE - LD A,0 - LD (TMPLINECNT),A -PRTSTR1: LD A,(DE) - CP 000H - JR Z,PRTSTRE - CP 00DH - JR Z,PRTSTR3 -PRTSTR2: CALL PRNT - INC DE - JR PRTSTR1 -PRTSTR3: PUSH AF - LD A,(TMPLINECNT) - CP 24 - JR Z,PRTSTR5 - INC A -PRTSTR4: LD (TMPLINECNT),A - POP AF - JR PRTSTR2 -PRTSTR5: CALL GETKY - CP ' ' - JR NZ,PRTSTR5 - XOR A - JR PRTSTR4 -PRTSTRE: POP DE - POP BC - POP AF - RET - - ; Help text. Use of lower case, due to Sharp's non standard character set, is not easy, you have to manually code each byte - ; hence using upper case. -HELPSCR: DB "4 - 40 COL MODE.", 00DH - DB "8 - 80 COL MODE.", 00DH - DB "B - TOGGLE KEYBOARD BELL.", 00DH - DB "C - CLEAR MEMORY $1200-$D000.", 00DH - DB "DXXXX[YYYY] - DUMP MEM XXXX TO YYYY.", 00DH - DB "F[X] - BOOT FD DRIVE X.", 00DH - DB 0AAH," - BOOT FD ORIGINAL ROM.", 00DH - DB "H - THIS HELP SCREEN.", 00DH - DB "IR/IC - RFS DIR LISTING ROM/SD CARD.", 00DH - DB "JXXXX - JUMP TO LOCATION XXXX.", 00DH - DB "LT[FN]- LOAD TAPE, FN=FILENAME", 00DH - DB "LR[FN]- LOAD ROM, FN=NO OR NAME", 00DH - DB "LC[FN]- LOAD SDCARD, FN=NO OR NAME", 00DH - DB " - ADD NX FOR NO EXEC, IE.LRNX.", 00DH - DB "MXXXX - EDIT MEMORY STARTING AT XXXX.", 00DH - DB "P - TEST PRINTER.", 00DH - DB "R - TEST DRAM MEMORY.", 00DH - DB "ST[XXXXYYYYZZZZ] - SAVE MEM TO TAPE.", 00DH - DB "SC[XXXXYYYYZZZZ] - SAVE MEM TO CARD.", 00DH - DB " XXXX=START,YYYY=END,ZZZZ=EXEC", 00DH - DB "T - TEST TIMER.", 00DH - DB "V - VERIFY TAPE SAVE.", 00DH - DB 000H - - ;------------------------------------------------------------------------------- - ; END OF HELP SCREEN FUNCTIONALITY - ;------------------------------------------------------------------------------- - ;-------------------------------------- ; - ; Message table + ; Message table - Refer to bank 6 for + ; all messages. ; ;-------------------------------------- -MSG_INITM: DB "INIT MEMORY", 00DH - ALIGN 0EFFFh DB 0FFh diff --git a/software/asm/rfs_bank4.asm b/software/asm/rfs_bank4.asm index 1b82a7f..7cd3bb1 100644 --- a/software/asm/rfs_bank4.asm +++ b/software/asm/rfs_bank4.asm @@ -88,14 +88,13 @@ BKSW4to7: PUSH AF PUSH AF LD A, ROMBANK7 ; Required bank to call. ; -BKSW4_0: PUSH BC ; Save BC for caller. - LD BC, BKSWRET4 ; Place bank switchers return address on stack. - PUSH BC - LD (RFSBK2), A ; Bank switch in user rom space, A=bank. +BKSW4_0: PUSH HL ; Place function to call on stack + LD HL, BKSWRET4 ; Place bank switchers return address on stack. + EX (SP),HL LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it. + LD (RFSBK2), A ; Bank switch in user rom space, A=bank. JP (HL) ; Jump to required function. -BKSWRET4: POP BC - POP AF ; Get bank which called us. +BKSWRET4: POP AF ; Get bank which called us. LD (RFSBK2), A ; Return to that bank. POP AF RET ; Return to caller. @@ -105,42 +104,61 @@ BKSWRET4: POP BC ; START OF CMT CONTROLLER FUNCTIONALITY ;------------------------------------------------------------------------------- -; Programm load -; -; cmd. 'L' -; -LOADTAPENX: LD L,0FFH + ; CMT Utility to Load a program from tape. + ; + ; Three entry points: + ; LOADTAPE = Load the first program shifting to lo memory if required and execute. + ; LOADTAPENX = Load the first program and return without executing. + ; LOADTAPECP = Load the first program to address 0x1200 and return. + ; +LOADTAPECP: LD A,0FFH + LD (CMTAUTOEXEC),A + JR LOADTAPE2 +LOADTAPENX: LD A,0FFH JR LOADTAPE1 -LOADTAPE: LD L,000H -LOADTAPE1: PUSH HL ; Preserve auto execute flag. +LOADTAPE: LD A,000H +LOADTAPE1: LD (CMTAUTOEXEC),A + XOR A +LOADTAPE2: LD (CMTCOPY),A ; Set cmt copy mode, 0xFF if we are copying. + LD A,0FFH ; If called interbank, set a result code in memory to detect success. + LD (RESULT),A CALL ?RDI JP C,?ERX2 - CALL NL - LD DE,MSG?2 ; 'LOADING ' - RST 018h - LD DE,NAME - RST 018h + LD DE,MSGLOAD ; 'LOADING ' + LD BC,NAME + LD HL,PRINTMSG + CALL BKSW4to6 XOR A - LD (BUFER),A - LD HL,(DTADR) + LD (CMTLOLOAD),A + + LD HL,(DTADR) ; Common code, store load address in case we shift or manipulate loading. + LD (DTADRSTORE),HL + + LD A,(CMTCOPY) ; If were copying we always load at 0x1200. + OR A + JR Z,LOADTAPE3 + LD HL,01200H + LD (DTADR),HL + +LOADTAPE3: LD HL,(DTADR) ; If were loading and the load address is below 0x1200, shift it to 0x1200 to load then move into correct location. LD A,H OR L - JR NZ,LE941 - LD HL,(EXADR) - LD A,H - OR L - JR NZ,LE941 + JR NZ,LOADTAPE4 LD A,0FFh - LD (BUFER),A + LD (CMTLOLOAD),A LD HL,01200h LD (DTADR),HL -LE941: CALL ?RDD +LOADTAPE4: CALL ?RDD JP C,?ERX2 - POP HL ; Get back the auto execute flag. - LD A,L + LD HL,(DTADRSTORE) ; Restore the original load address into the CMT header. + LD (DTADR),HL + LD A,(CMTCOPY) OR A - JR Z,LOADTAPE4 ; Dont execute. - LD A,(BUFER) + JR NZ,LOADTAPE6 +LOADTAPE5: LD A,(CMTAUTOEXEC) ; Get back the auto execute flag. + OR A + JR NZ,LOADTAPE6 ; Dont execute.. + LD A,(CMTLOLOAD) CP 0FFh JR Z,LOADTAPELM ; Execute at low memory? LD BC,00100h @@ -152,56 +170,127 @@ LOADTAPELM: LD A,(MEMSW) ; Perfo LD BC,(SIZE) LDIR LD BC,00100h - JP 00000h -LOADTAPE4: RET - -; -; Programm save -; -; cmd. 'S' -; -SAVEX: CALL HEXIY ; Start address - LD (DTADR),HL ; data adress buffer - LD B,H - LD C,L - CALL INC4DE - CALL HEXIY ; End address - SBC HL,BC ; byte size - INC HL - LD (SIZE),HL ; byte size buffer - CALL INC4DE - CALL HEXIY ; execute address - LD (EXADR),HL ; buffer - CALL NL - LD DE,MSGSAVE ; 'FILENAME? ' - RST 018h - CALL GETLHEX ; filename input - CALL INC4DE - CALL INC4DE - LD HL,NAME ; name buffer -SAVX1: INC DE - LD A,(DE) - LD (HL),A ; filename trans. - INC HL - CP 00Dh ; end code - JR NZ,SAVX1 - LD A,OBJCD ; attribute: OBJ - LD (ATRB),A - CALL ?WRI -?ERX1: JP C,?ERX2 - CALL ?WRD ; data - JR C,?ERX1 - CALL NL - LD DE,MSGOK ; 'OK!' - RST 018h + LD HL,(EXADR) ; Fetch exec address and run. + JP (HL) +LOADTAPE6: LD DE,MSGCMTDATA + PUSH HL ; Load address as parameter 2. + LD HL,(EXADR) + PUSH HL ; Execution address as parameter 1. + LD BC,(SIZE) ; Size as BC parameter. + LD HL,PRINTMSG + CALL BKSW4to6 + POP BC + POP BC ; Waste parameters. + XOR A ; Success. + LD (RESULT),A RET + + ; SA1510 Routine to write a tape header. Copied into the RFS and modified to merge better + ; with the RFS interface. + ; +CMTWRI: DI + PUSH DE + PUSH BC + PUSH HL + LD D,0D7H + LD E,0CCH + LD HL,IBUFE + LD BC,00080H + CALL CKSUM + CALL MOTOR + JR C,CMTWRI2 + LD A,E + CP 0CCH + JR NZ,CMTWRI1 + PUSH HL + PUSH DE + PUSH BC + LD DE,MSGCMTWRITE + LD BC,NAME + LD HL,PRINTMSG + CALL BKSW4to6 + POP BC + POP DE + POP HL +CMTWRI1: CALL GAP + CALL WTAPE +CMTWRI2: POP HL + POP BC + POP DE + CALL MSTOP + PUSH AF + LD A,(TIMFG) + CP 0F0H + JR NZ,CMTWRI3 + EI +CMTWRI3: POP AF + RET + + + ; Method to save an application stored in memory to a cassette in the CMT. The start, size and execution address are either given in BUFER via the + ; command line and the a filename is prompted for and read, or alternatively all the data is passed into the function already set in the CMT header. + ; The tape is then opened and the header + data are written out. + ; +SAVECMT: LD A,0FFH ; Set SDCOPY to indicate this is a copy command and not a command line save. + JR SAVEX1 + ; + ; Normal entry point, the cmdline contains XXXXYYYYZZZZ where XXXX=start, YYYY=size, ZZZZ=exec addr. A filenname is prompted for and read. + ; The data is stored in the CMT header prior to writing out the header and data.. + ; +SAVEX: LD HL,GETCMTPARM ; Get the CMT parameters. + CALL BKSW4to3 + LD A,C + OR A + RET NZ ; Exit if an error occurred. + + XOR A +SAVEX1: LD (SDCOPY),A + LD A,0FFH + LD (RESULT),A ; For interbank calls, pass result via a memory variable. Assume failure unless updated. + LD A,OBJCD ; Set attribute: OBJ + LD (ATRB),A + CALL CMTWRI ; Commence header write. Header doesnt need updating for header write. +?ERX1: JP C,?ERX2 + + LD A,(SDCOPY) + OR A + JR Z,SAVEX2 + LD DE,(DTADR) + LD A,D ; If copying and address is below 1000H, then data is held at 1200H so update header for write. + CP 001H + JR NC,SAVEX2 + LD DE,01200H + LD (DTADR),DE +SAVEX2: CALL ?WRD ; data + JR C,?ERX1 + LD DE,MSGSAVEOK ; 'OK!' + LD HL,PRINTMSG + CALL BKSW4to6 + LD A,0 ; Success. + LD (RESULT),A + RET +?ERX2: CP 002h + JR NZ,?ERX3 + LD (RESULT),A ; Set break key pressed code. + RET Z +?ERX3: LD DE,MSGE1 ; 'CHECK SUM ER.' + LD HL,PRINTMSG + CALL BKSW4to6 + RET + + + ; Method to verify that a tape write occurred free of error. After a write, the tape is read and compared with the memory that created it. + ; VRFYX: CALL ?VRFY JP C,?ERX2 LD DE,MSGOK ; 'OK!' - RST 018h + LD HL,PRINTMSG + CALL BKSW4to6 RET + ; Method to toggle the audible key press sound, ie a beep when a key is pressed. + ; SGX: LD A,(SWRK) RRA CCF @@ -209,90 +298,16 @@ SGX: LD A,(SWRK) LD (SWRK),A RET -?ERX2: CP 002h - RET Z - CALL NL - LD DE,MSGE1 ; 'CHECK SUM ER.' - RST 018h - RET - -HEXIY: EX (SP),IY - POP AF - CALL HLHEX - JR C,HEXIY ; Exit if the input is invalid - JP (IY) -HEXIY2: POP AF ; Waste the intermediate caller address - RET ; Return to command processor. - - ; INCREMENT DE REG. -INC4DE: INC DE - INC DE - INC DE - INC DE - RET - -GETLHEX: EX (SP),HL - POP BC - LD DE,BUFER - CALL GETL - LD A,(DE) - CP 01Bh - JR Z,HEXIY2 - JP (HL) - - -;FNINP: CALL NL -; LD DE,MSGSV ; 'FILENAME? ' -; RST 018h -; LD DE,BUFER -; CALL GETL -; LD A,(DE) -; CP #1B -; JR NZ,LEAF3 -; ;LD HL,ST1X -; ;EX (SP),HL -; RET -; -;LEAF3: LD B,000h -; LD DE,011ADh -; LD HL,BUFER -; LD A,(DE) -; CP 00Dh -; JR Z,LEB20 -;LEB00: CP 020h -; JR NZ,LEB08 -; INC DE -; LD A,(DE) -; JR LEB00 -;LEB08: CP 022h -; JR Z,LEB14 -;LEB0C: LD (HL),A -; INC HL -; INC B -; LD A,011h -; CP B -; JR Z,FNINP -;LEB14: INC DE -; LD A,(DE) -; CP 022h -; JR Z,LEB1E -; CP 00Dh -; JR NZ,LEB0C -;LEB1E: LD A,00dh -;LEB20: LD (HL),A -; RET -; - ;------------------------------------------------------------------------------- ; END OF CMT CONTROLLER FUNCTIONALITY ;------------------------------------------------------------------------------- ;-------------------------------------- ; - ; Message table + ; Message table - Refer to bank 6 for + ; all messages. ; ;-------------------------------------- -MSGSAVE: DB "FILENAME? ", 00DH ALIGN 0EFFFh DB 0FFh diff --git a/software/asm/rfs_bank5.asm b/software/asm/rfs_bank5.asm index 56476b9..d886d07 100644 --- a/software/asm/rfs_bank5.asm +++ b/software/asm/rfs_bank5.asm @@ -88,14 +88,13 @@ BKSW5to7: PUSH AF PUSH AF LD A, ROMBANK7 ; Required bank to call. ; -BKSW5_0: PUSH BC ; Save BC for caller. - LD BC, BKSWRET5 ; Place bank switchers return address on stack. - PUSH BC - LD (RFSBK2), A ; Bank switch in user rom space, A=bank. +BKSW5_0: PUSH HL ; Place function to call on stack + LD HL, BKSWRET5 ; Place bank switchers return address on stack. + EX (SP),HL LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it. + LD (RFSBK2), A ; Bank switch in user rom space, A=bank. JP (HL) ; Jump to required function. -BKSWRET5: POP BC - POP AF ; Get bank which called us. +BKSWRET5: POP AF ; Get bank which called us. LD (RFSBK2), A ; Return to that bank. POP AF RET ; Return to caller. diff --git a/software/asm/rfs_bank6.asm b/software/asm/rfs_bank6.asm index 52ebbf3..8876ab0 100644 --- a/software/asm/rfs_bank6.asm +++ b/software/asm/rfs_bank6.asm @@ -88,19 +88,369 @@ BKSW6to7: PUSH AF PUSH AF LD A, ROMBANK7 ; Required bank to call. ; -BKSW6_0: PUSH BC ; Save BC for caller. - LD BC, BKSWRET6 ; Place bank switchers return address on stack. - PUSH BC - LD (RFSBK2), A ; Bank switch in user rom space, A=bank. +BKSW6_0: PUSH HL ; Place function to call on stack + LD HL, BKSWRET6 ; Place bank switchers return address on stack. + EX (SP),HL LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it. + LD (RFSBK2), A ; Bank switch in user rom space, A=bank. JP (HL) ; Jump to required function. -BKSWRET6: POP BC - POP AF ; Get bank which called us. +BKSWRET6: POP AF ; Get bank which called us. LD (RFSBK2), A ; Return to that bank. POP AF RET ; Return to caller. + ;------------------------------------------------------------------------------- + ; START OF PRINT ROUTINE METHODS + ;------------------------------------------------------------------------------- + + ; Method to print out a true ASCII character, not the Sharp values. This is done using the mapping table ATBL for the + ; range 0..127, 128.. call the original Sharp routine. + ; Input: A = Ascii character. +PRINTASCII: PUSH HL + PUSH BC + CP 080H ; Anything above 080H isnt ascii so call original routine. + JR NC,PRINTASCII1 + CP 00DH ; Carriage Return? Dont map just execute via original Sharp call. + JR Z,PRINTASCII1 + LD HL,ATBL + LD C,A + LD B,0 + ADD HL,BC + LD A,(HL) + CALL ?DSP +PRINTASCII0:POP BC + POP HL + RET +PRINTASCII1:CALL PRNT + JR PRINTASCII0 + + ; Method to print out a string residing in this bank. + ; + ; As string messages take up space and banks are limited, it makes sense to locate all strings in one + ; bank and print them out from here, hence this method. + ; + ; Also, as strings often require embedded values to be printed (aka printf), a basic mechanism for printing out stack + ; parameters is provided. A PUSH before calling this method followed by an embedded marker (ie. 0xFF) will see the stack + ; value printed in hex at the point in the string where the marker appears. + ; + ; Input: DE = Address, in this bank or any other location EXCEPT another bank. + ; BC = Value to print with marker 0xFB if needed. + ; Upto 4 stack values accessed by markers 0xFF, 0xFE, 0xFD, 0xFC +PRINTMSG: LD A,(DE) + CP 000H ; End of string? + RET Z + CP 0FFH ; Marker to print out first stack parameter. + JR Z,PRINTMSG3 + CP 0FEH ; Marker to print out second stack parameter. + JR Z,PRINTMSG6 + CP 0FDH ; Marker to print out third stack parameter. + JR Z,PRINTMSG7 + CP 0FCH ; Marker to print out fourth stack parameter. + JR Z,PRINTMSG8 + CP 0FBH ; Marker to print out BC. + JR Z,PRINTMSG9 + CP 0FAH ; Marker to print out a filename with filename address stored in BC. + JR Z,PRINTMSG10 + CALL PRINTASCII +PRINTMSG2: INC DE + JR PRINTMSG +PRINTMSG3: LD HL,8+0 ; Get first stack parameter, there are 2 pushes on the stack plus return address before the parameters. +PRINTMSG4: ADD HL,SP + LD A,(HL) + INC HL + LD H,(HL) + LD L,A +PRINTMSG5: CALL PRTHL + JR PRINTMSG2 +PRINTMSG6: LD HL,8+2 + JR PRINTMSG4 +PRINTMSG7: LD HL,8+4 + JR PRINTMSG4 +PRINTMSG8: LD HL,8+6 + JR PRINTMSG4 +PRINTMSG9: PUSH BC ; Print out contents of BC as 4 digit hex. + POP HL + JR PRINTMSG5 +PRINTMSG10: PUSH DE ; Print out a filename with pointer stored in BC. + PUSH BC + POP DE + CALL PRTFN + POP DE + JR PRINTMSG2 + + + ; Method to print out the filename within an MZF header or SD Card header. + ; The name may not be terminated as the full 17 chars are used, so this needs + ; to be checked. Also, the filename uses Sharp Ascii so call the original Sharp + ; print routine. + ; + ; Input: DE = Address of filename. + ; +PRTFN: PUSH BC + LD B,FNSIZE ; Maximum size of filename. +PRTMSG: LD A,(DE) + INC DE + CP 000H ; If there is a valid terminator, exit. + JR Z,PRTMSGE + CP 00DH + JR Z,PRTMSGE + CALL PRNT + DJNZ PRTMSG ; Else print until 17 chars have been processed. + CALL NL +PRTMSGE: POP BC + RET + ;------------------------------------------------------------------------------- + ; END OF PRINT ROUTINE METHODS + ;------------------------------------------------------------------------------- + + + + ;------------------------------------------------------------------------------- + ; START OF HELP SCREEN FUNCTIONALITY + ;------------------------------------------------------------------------------- + + ; Simple help screen to display commands. +HELP: CALL NL + LD DE, HELPSCR + CALL PRTSTR + RET + + ; A modified print string routine with full screen pause to print out the help screen text. The routine prints out true ascii + ; as opposed to Sharp modified ascii. + ; A string is NULL terminated. +PRTSTR: PUSH AF + PUSH BC + PUSH DE + LD A,0 + LD (TMPLINECNT),A +PRTSTR1: LD A,(DE) + CP 000H ; NULL terminates the string. + JR Z,PRTSTRE + CP 00DH ; As does CR. + JR Z,PRTSTR3 +PRTSTR2: CALL PRINTASCII + INC DE + JR PRTSTR1 +PRTSTR3: PUSH AF + LD A,(TMPLINECNT) + CP 24 + JR Z,PRTSTR5 + INC A +PRTSTR4: LD (TMPLINECNT),A + POP AF + JR PRTSTR2 +PRTSTR5: CALL GETKY + CP ' ' + JR NZ,PRTSTR5 + XOR A + JR PRTSTR4 +PRTSTRE: POP DE + POP BC + POP AF + RET + + ; Help text. Use of lower case, due to Sharp's non standard character set, is not easy, you have to manually code each byte + ; hence using upper case. +HELPSCR: DB "4 - 40 col mode.", 00DH + DB "8 - 80 col mode.", 00DH + DB "B - toggle keyboard bell.", 00DH + DB "C - clear memory $1200-$D000.", 00DH + DB "DXXXX[YYYY] - dump mem XXXX to YYYY.", 00DH + DB "EC[FN]- erase file, FN=No, or Filename", 00DH + DB "F[X] - boot fd drive X.", 00DH + DB "f - boot fd original rom.", 00DH + DB "H - this help screen.", 00DH + DB "IR/IC - rfs dir listing rom/sd card.", 00DH + DB "JXXXX - jump to location XXXX.", 00DH + DB "LT[FN]- load tape, FN=Filename", 00DH + DB "LR[FN]- load rom, FN=No. or Filename", 00DH + DB "LC[FN]- load sdcard, FN=No. or Filename", 00DH + DB " - add NX for no exec, ie.LRNX.", 00DH + DB "MXXXX - edit memory starting at XXXX.", 00DH + DB "P - test printer.", 00DH + DB "R - test dram memory.", 00DH + DB "SD2T - copy sd card to tape.", 00DH + DB "ST[XXXXYYYYZZZZ] - save mem to tape.", 00DH + DB "SC[XXXXYYYYZZZZ] - save mem to card.", 00DH + DB " XXXX=start,YYYY=end,ZZZZ=exec", 00DH + DB "T - test timer.", 00DH + DB "T2SD - copy tape to sd card.", 00DH + DB "V - verify tape save.", 00DH + DB 000H + + ;------------------------------------------------------------------------------- + ; END OF HELP SCREEN FUNCTIONALITY + ;------------------------------------------------------------------------------- + + ; TRUE ASCII TO DISPLAY CODE TABLE + ; +ATBL: DB 0CCH ; NUL '\0' (null character) + DB 0E0H ; SOH (start of heading) + DB 0F2H ; STX (start of text) + DB 0F3H ; ETX (end of text) + DB 0CEH ; EOT (end of transmission) + DB 0CFH ; ENQ (enquiry) + DB 0F6H ; ACK (acknowledge) + DB 0F7H ; BEL '\a' (bell) + DB 0F8H ; BS '\b' (backspace) + DB 0F9H ; HT '\t' (horizontal tab) + DB 0FAH ; LF '\n' (new line) + DB 0FBH ; VT '\v' (vertical tab) + DB 0FCH ; FF '\f' (form feed) + DB 0FDH ; CR '\r' (carriage ret) + DB 0FEH ; SO (shift out) + DB 0FFH ; SI (shift in) + DB 0E1H ; DLE (data link escape) + DB 0C1H ; DC1 (device control 1) + DB 0C2H ; DC2 (device control 2) + DB 0C3H ; DC3 (device control 3) + DB 0C4H ; DC4 (device control 4) + DB 0C5H ; NAK (negative ack.) + DB 0C6H ; SYN (synchronous idle) + DB 0E2H ; ETB (end of trans. blk) + DB 0E3H ; CAN (cancel) + DB 0E4H ; EM (end of medium) + DB 0E5H ; SUB (substitute) + DB 0E6H ; ESC (escape) + DB 0EBH ; FS (file separator) + DB 0EEH ; GS (group separator) + DB 0EFH ; RS (record separator) + DB 0F4H ; US (unit separator) + DB 000H ; SPACE + DB 061H ; ! + DB 062H ; " + DB 063H ; # + DB 064H ; $ + DB 065H ; % + DB 066H ; & + DB 067H ; ' + DB 068H ; ( + DB 069H ; ) + DB 06BH ; * + DB 06AH ; + + DB 02FH ; , + DB 02AH ; - + DB 02EH ; . + DB 02DH ; / + DB 020H ; 0 + DB 021H ; 1 + DB 022H ; 2 + DB 023H ; 3 + DB 024H ; 4 + DB 025H ; 5 + DB 026H ; 6 + DB 027H ; 7 + DB 028H ; 8 + DB 029H ; 9 + DB 04FH ; : + DB 02CH ; ; + DB 051H ; < + DB 02BH ; = + DB 057H ; > + DB 049H ; ? + DB 055H ; @ + DB 001H ; A + DB 002H ; B + DB 003H ; C + DB 004H ; D + DB 005H ; E + DB 006H ; F + DB 007H ; G + DB 008H ; H + DB 009H ; I + DB 00AH ; J + DB 00BH ; K + DB 00CH ; L + DB 00DH ; M + DB 00EH ; N + DB 00FH ; O + DB 010H ; P + DB 011H ; Q + DB 012H ; R + DB 013H ; S + DB 014H ; T + DB 015H ; U + DB 016H ; V + DB 017H ; W + DB 018H ; X + DB 019H ; Y + DB 01AH ; Z + DB 052H ; [ + DB 059H ; \ '\\' + DB 054H ; ] + DB 0BEH ; ^ + DB 03CH ; _ + DB 0C7H ; ` + DB 081H ; a + DB 082H ; b + DB 083H ; c + DB 084H ; d + DB 085H ; e + DB 086H ; f + DB 087H ; g + DB 088H ; h + DB 089H ; i + DB 08AH ; j + DB 08BH ; k + DB 08CH ; l + DB 08DH ; m + DB 08EH ; n + DB 08FH ; o + DB 090H ; p + DB 091H ; q + DB 092H ; r + DB 093H ; s + DB 094H ; t + DB 095H ; u + DB 096H ; v + DB 097H ; w + DB 098H ; x + DB 099H ; y + DB 09AH ; z + DB 0BCH ; { + DB 080H ; | + DB 040H ; } + DB 0A5H ; ~ + DB 0C0H ; DEL + + ;-------------------------------------- + ; + ; Message table + ; + ;-------------------------------------- +MSGSON: DB "+ RFS ", 0ABh, "1.2 **" ,00DH, 000H +MSGNOTFND: DB "Not Found", 00DH, 000H +MSGRDIRLST: DB "ROM Directory:", 00DH, 000H +MSGTRM: DB 00DH, 000H +MSGBADCMD: DB "???", 00DH, 000H +MSGCDIRLST: DB "SD Card Directory:", 00DH, 000H +MSGSDRERR: DB "SD Read error, Sec:",0FBH, 000H +MSGSDWERR: DB "SD Write error, Sec:",0FBH, 000H +MSGSVFAIL: DB "SD Error, save failed.", 00DH, 000H +MSGERAFAIL: DB "SD Dir update failed.", 00DH, 000H +MSGSVDIRENT:DB "Saving into dir entry:",0FBH, 00DH, 000H +MSGERASEDIR:DB "Deleted dir entry:",0FBH, 000H +MSGCMTDATA: DB "Load:",0FEH,",Exec:",0FFH, ",Size:",0FBH, 00DH, 000H +MSGNOTBIN: DB "Not binary", 00DH, 000H +MSGLOAD: DB 00DH, "Loading ",'"',0FAH,'"', 00DH, 000H +MSGSAVE: DB 00DH, "Filename: ", 000H +MSGDIRFULL: DB "Directory full", 00DH, 000H +MSGE1: DB 00DH, "Check sum error!", 00DH, 000H ; Check sum error. +MSGCMTWRITE:DB 00DH, "Writing ", '"',0FAH,'"', 00DH, 000H +MSGOK: DB 00DH, "OK!", 00DH, 000H +MSGSAVEOK: DB "Tape image saved.", 00DH, 000H +MSGBOOTDRV: DB 00DH, "Floppy boot drive ?", 000H +MSGLOADERR: DB 00DH, "Disk loading error", 00DH, 000H +MSGIPLLOAD: DB 00DH, "Disk loading ", 000H +MSGDSKNOTMST:DB 00DH, "This is not a boot disk",00Dh, 000H +MSGINITM: DB "Init memory", 00DH, 000H +MSGREAD4HEX:DB "Bad hex number", 00DH, 000H +MSGT2SDERR: DB "Copy from Tape to SD Failed", 00DH, 000H +MSGSD2TERR: DB "Copy from SD to Tape Failed", 00DH, 000H +MSGT2SDOK: DB "Success, Tape to SD done.", 00DH, 000H +MSGSD2TOK: DB "Success, SD to Tape done.", 00DH, 000H + ALIGN 0EFFFh DB 0FFh diff --git a/software/asm/rfs_bank7.asm b/software/asm/rfs_bank7.asm index ca8d07b..a3f04ce 100644 --- a/software/asm/rfs_bank7.asm +++ b/software/asm/rfs_bank7.asm @@ -88,14 +88,13 @@ BKSW7to7: PUSH AF PUSH AF LD A, ROMBANK7 ; Required bank to call. ; -BKSW7_0: PUSH BC ; Save BC for caller. - LD BC, BKSWRET7 ; Place bank switchers return address on stack. - PUSH BC - LD (RFSBK2), A ; Bank switch in user rom space, A=bank. +BKSW7_0: PUSH HL ; Place function to call on stack + LD HL, BKSWRET7 ; Place bank switchers return address on stack. + EX (SP),HL LD (TMPSTACKP),SP ; Save the stack pointer as some old code corrupts it. + LD (RFSBK2), A ; Bank switch in user rom space, A=bank. JP (HL) ; Jump to required function. -BKSWRET7: POP BC - POP AF ; Get bank which called us. +BKSWRET7: POP AF ; Get bank which called us. LD (RFSBK2), A ; Return to that bank. POP AF RET ; Return to caller. diff --git a/software/roms/MROM_256.bin b/software/roms/MROM_256.bin index 3925cea..17491b7 100644 Binary files a/software/roms/MROM_256.bin and b/software/roms/MROM_256.bin differ diff --git a/software/roms/USER_ROM_256.bin b/software/roms/USER_ROM_256.bin index 79d56f3..ff39a5a 100644 Binary files a/software/roms/USER_ROM_256.bin and b/software/roms/USER_ROM_256.bin differ diff --git a/software/roms/cbios.rom b/software/roms/cbios.rom index 3099705..885ea1e 100644 Binary files a/software/roms/cbios.rom and b/software/roms/cbios.rom differ diff --git a/software/roms/rfs.rom b/software/roms/rfs.rom index 4e2c518..53a0c17 100644 Binary files a/software/roms/rfs.rom and b/software/roms/rfs.rom differ diff --git a/software/tools/make_sdcard.sh b/software/tools/make_sdcard.sh index 5be6ccf..4986dba 100755 --- a/software/tools/make_sdcard.sh +++ b/software/tools/make_sdcard.sh @@ -56,17 +56,13 @@ RFS_INCLUDE+="${MZF_PATH}/2z-046a.MZF:" RFS_INCLUDE+="${MZF_PATH}/5Z-009A.MZF:" RFS_INCLUDE+="${MZF_PATH}/5Z-009B.MZF:" RFS_INCLUDE+="${MZF_PATH}/6502_Betriebssys.MZF:" -RFS_INCLUDE+="${MZF_PATH}/80A PENCIL.A2_C2.MZF:" RFS_INCLUDE+="${MZF_PATH}/80A_PENCIL.A2_C2.MZF:" -RFS_INCLUDE+="${MZF_PATH}/80A PENCIL.A2_S.MZF:" RFS_INCLUDE+="${MZF_PATH}/80A_PENCIL.A2_S.MZF:" RFS_INCLUDE+="${MZF_PATH}/80zbasic.MZF:" RFS_INCLUDE+="${MZF_PATH}/A-BASIC_SA-5510.MZF:" RFS_INCLUDE+="${MZF_PATH}/AIP_-_LOGO_xrr.MZF:" -RFS_INCLUDE+="${MZF_PATH}/APOLLO CHESS v2a.MZF:" RFS_INCLUDE+="${MZF_PATH}/APOLLO_CHESS_v2a.MZF:" RFS_INCLUDE+="${MZF_PATH}/B880.A3_P6.MZF:" -RFS_INCLUDE+="${MZF_PATH}/B880 MASTER.MZF:" RFS_INCLUDE+="${MZF_PATH}/B880_MASTER.MZF:" RFS_INCLUDE+="${MZF_PATH}/BASIC_MZ-5Z008_2.MZF:" RFS_INCLUDE+="${MZF_PATH}/BASIC_MZ-5Z008.MZF:" @@ -77,37 +73,25 @@ RFS_INCLUDE+="${MZF_PATH}/BASIC_OM-1001.MZF:" RFS_INCLUDE+="${MZF_PATH}/BASIC_OM-500.MZF:" RFS_INCLUDE+="${MZF_PATH}/basic_sa-5510.MZF:" RFS_INCLUDE+="${MZF_PATH}/BASIC.SA-5510.MZF:" -RFS_INCLUDE+="${MZF_PATH}/BASIC SA-5575_C.MZF:" RFS_INCLUDE+="${MZF_PATH}/BASIC_SA-5575_C.MZF:" -RFS_INCLUDE+="${MZF_PATH}/BASIC SA-5575_S.MZF:" RFS_INCLUDE+="${MZF_PATH}/BASIC_SA-5575_S.MZF:" -RFS_INCLUDE+="${MZF_PATH}/BASIC SA-5577_C.MZF:" RFS_INCLUDE+="${MZF_PATH}/BASIC_SA-5577_C.MZF:" -RFS_INCLUDE+="${MZF_PATH}/BASIC SA-5577_S.MZF:" RFS_INCLUDE+="${MZF_PATH}/BASIC_SA-5577_S.MZF:" -RFS_INCLUDE+="${MZF_PATH}/BASIC SA-5580.MZF:" RFS_INCLUDE+="${MZF_PATH}/BASIC_SA-5580.MZF:" RFS_INCLUDE+="${MZF_PATH}/BASIC_SP-5025.MZF:" -RFS_INCLUDE+="${MZF_PATH}/BAS MOD v3.74.MZF:" RFS_INCLUDE+="${MZF_PATH}/BAS_MOD_v3.74.MZF:" RFS_INCLUDE+="${MZF_PATH}/BATTLE_GAME.MZF:" -RFS_INCLUDE+="${MZF_PATH}/BINARY COUNT.MZF:" RFS_INCLUDE+="${MZF_PATH}/BINARY_COUNT.MZF:" RFS_INCLUDE+="${MZF_PATH}/bomberman_MZ700.m12:" -RFS_INCLUDE+="${MZF_PATH}/BYTESAVER SA5510.MZF:" RFS_INCLUDE+="${MZF_PATH}/BYTESAVER_SA5510.MZF:" RFS_INCLUDE+="${MZF_PATH}/cannon_ball.m12:" RFS_INCLUDE+="${MZF_PATH}/clock1.MZF:" -RFS_INCLUDE+="${MZF_PATH}/CLUB COPY.U1.MZF:" RFS_INCLUDE+="${MZF_PATH}/CLUB_COPY.U1.MZF:" -RFS_INCLUDE+="${MZF_PATH}/CLUB MON.A1_M.MZF:" RFS_INCLUDE+="${MZF_PATH}/CLUB_MON.A1_M.MZF:" -RFS_INCLUDE+="${MZF_PATH}/CLUB MON.A1_S.MZF:" RFS_INCLUDE+="${MZF_PATH}/CLUB_MON.A1_S.MZF:" RFS_INCLUDE+="${MZF_PATH}/cmttofd.MZF:" RFS_INCLUDE+="${MZF_PATH}/COLONY.MZF:" RFS_INCLUDE+="${MZF_PATH}/COMPILER_A2.MZF:" -RFS_INCLUDE+="${MZF_PATH}/CONVERTER A_700.MZF:" RFS_INCLUDE+="${MZF_PATH}/CONVERTER_A_700.MZF:" RFS_INCLUDE+="${MZF_PATH}/CONVERTER.MZF:" RFS_INCLUDE+="${MZF_PATH}/COPIER.MZF:" @@ -116,26 +100,19 @@ RFS_INCLUDE+="${MZF_PATH}/cpm22.MZF:" RFS_INCLUDE+="${MZF_PATH}/CPM_RFS_1.MZF:" RFS_INCLUDE+="${MZF_PATH}/CPM_RFS_2.MZF:" RFS_INCLUDE+="${MZF_PATH}/CRUISER3_MZ1500.M12:" -RFS_INCLUDE+="${MZF_PATH}/DCS MZ80A APPEND.MZF:" RFS_INCLUDE+="${MZF_PATH}/DCS_MZ80A_APPEND.MZF:" -RFS_INCLUDE+="${MZF_PATH}/DCS MZ80A RENUM.MZF:" RFS_INCLUDE+="${MZF_PATH}/DCS_MZ80A_RENUM.MZF:" RFS_INCLUDE+="${MZF_PATH}/DELETE.MZF:" RFS_INCLUDE+="${MZF_PATH}/diamond.MZF:" -RFS_INCLUDE+="${MZF_PATH}/DISASM 8800.A15.MZF:" RFS_INCLUDE+="${MZF_PATH}/DISASM_8800.A15.MZF:" -RFS_INCLUDE+="${MZF_PATH}/DISASM B800.A15.MZF:" RFS_INCLUDE+="${MZF_PATH}/DISASM_B800.A15.MZF:" RFS_INCLUDE+="${MZF_PATH}/DISKEDIT.A4B.MZF:" RFS_INCLUDE+="${MZF_PATH}/DISKEDIT.A7_40T.MZF:" RFS_INCLUDE+="${MZF_PATH}/diskutility.MZF:" RFS_INCLUDE+="${MZF_PATH}/doordoor:" RFS_INCLUDE+="${MZF_PATH}/Doordoor.mzt:" -RFS_INCLUDE+="${MZF_PATH}/EXPRESS BAS_700.MZF:" RFS_INCLUDE+="${MZF_PATH}/EXPRESS_BAS_700.MZF:" -RFS_INCLUDE+="${MZF_PATH}/EXPRESS COMPILER.MZF:" RFS_INCLUDE+="${MZF_PATH}/EXPRESS_COMPILER.MZF:" -RFS_INCLUDE+="${MZF_PATH}/EXPRESS PLUS.MZF:" RFS_INCLUDE+="${MZF_PATH}/EXPRESS_PLUS.MZF:" RFS_INCLUDE+="${MZF_PATH}/EXT.BASIC_OM-500.MZF:" RFS_INCLUDE+="${MZF_PATH}/FDCOPY.MZF:" @@ -220,7 +197,6 @@ RFS_INCLUDE+="${MZF_PATH}/ROUND_SHOOT.MZF:" RFS_INCLUDE+="${MZF_PATH}/sa-5510_Bas_MZ80K.MZF:" RFS_INCLUDE+="${MZF_PATH}/SA-5510_Compiler.MZF:" RFS_INCLUDE+="${MZF_PATH}/SA-5510+KN.COMM..MZF:" -RFS_INCLUDE+="${MZF_PATH}/SA-6510.DSK:" RFS_INCLUDE+="${MZF_PATH}/sa-6510.MZF:" RFS_INCLUDE+="${MZF_PATH}/SARGON_2.71.MZF:" RFS_INCLUDE+="${MZF_PATH}/S-Basic-Cent-2.MZF:" @@ -283,7 +259,6 @@ RFS_INCLUDE+="${MZF_PATH}/Z80MACHINE.A3_C2.MZF:" RFS_INCLUDE+="${MZF_PATH}/Z80_MACHINE.A3_S.MZF:" RFS_INCLUDE+="${MZF_PATH}/ZEN7E.A2.MZF:" RFS_INCLUDE+="${MZF_PATH}/Zexas_MZ800.MZF:" -RFS_INCLUDE+="${MZF_PATH}/ZSP:" RFS_INCLUDE+="${MZF_PATH}/ZSP.MZF" IFS=":"; for f in ${RFS_INCLUDE}