SD Card updates for CPM
This commit is contained in:
Binary file not shown.
Binary file not shown.
1
software/CPM/BLANKFD/BLANK_16M.RAW
Normal file
1
software/CPM/BLANKFD/BLANK_16M.RAW
Normal file
File diff suppressed because one or more lines are too long
BIN
software/CPM/CPM00_SYSTEM/DDT.COM
Normal file
BIN
software/CPM/CPM00_SYSTEM/DDT.COM
Normal file
Binary file not shown.
Binary file not shown.
BIN
software/CPM/CPM00_SYSTEM/ZSID_ORIG.COM
Normal file
BIN
software/CPM/CPM00_SYSTEM/ZSID_ORIG.COM
Normal file
Binary file not shown.
BIN
software/CPM/SDC16M/RAW/SDCDISK0.RAW
Normal file
BIN
software/CPM/SDC16M/RAW/SDCDISK0.RAW
Normal file
Binary file not shown.
BIN
software/CPM/SDC16M/RAW/SDCDISK1.RAW
Normal file
BIN
software/CPM/SDC16M/RAW/SDCDISK1.RAW
Normal file
Binary file not shown.
BIN
software/CPM/SDC16M/RAW/SDCDISK2.RAW
Normal file
BIN
software/CPM/SDC16M/RAW/SDCDISK2.RAW
Normal file
Binary file not shown.
BIN
software/CPM/SDC16M/RAW/SDCDISK3.RAW
Normal file
BIN
software/CPM/SDC16M/RAW/SDCDISK3.RAW
Normal file
Binary file not shown.
BIN
software/CPM/SDC16M/RAW/SDCDISK4.RAW
Normal file
BIN
software/CPM/SDC16M/RAW/SDCDISK4.RAW
Normal file
Binary file not shown.
BIN
software/CPM/SDC16M/RAW/SDCDISK5.RAW
Normal file
BIN
software/CPM/SDC16M/RAW/SDCDISK5.RAW
Normal file
Binary file not shown.
BIN
software/CPM/SDC16M/RAW/SDCDISK6.RAW
Normal file
BIN
software/CPM/SDC16M/RAW/SDCDISK6.RAW
Normal file
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -45,18 +45,30 @@
|
||||
NOP
|
||||
; After switching in Bank 0, it will automatically continue processing in Bank 0 at the XOR A instructionof ROMFS:
|
||||
|
||||
; Jump table for entry into this pages public functions.
|
||||
;-------------------------------------------------------------------------------
|
||||
; Jump table for entry into this pages functions.
|
||||
;-------------------------------------------------------------------------------
|
||||
JP ?REBOOT ; 9 REBOOT
|
||||
JP ?MLDY ; 12 QMELDY
|
||||
JP ?TEMP ; 15 QTEMP
|
||||
JP MLDST ; 18 QMSTA
|
||||
JP MLDSP ; 21 QMSTP
|
||||
JP ?BEL ; 24 QBEL
|
||||
JP ?MODE ; 27 QMODE
|
||||
JP ?TIMESET ; 30 QTIMESET
|
||||
JP ?TIMEREAD ; 33 QTIMEREAD
|
||||
JP ?CHKKY ; 36 QCHKKY
|
||||
JP ?GETKY ; 39 QGETKY
|
||||
|
||||
|
||||
|
||||
; Method to reboot the machine into startup mode, ie. Monitor at MROM Bank 0, UROM at Bank 0.
|
||||
?REBOOT: LD A,(MEMSWR) ; Switch memory to power up state, ie. Monitor ROM at 00000H
|
||||
JP UROMADDR ; Now run the code at the bank start which switches to bank 0, intitialises and then calls 00000H
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF AUDIO CONTROLLER FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; Melody function.
|
||||
?MLDY: PUSH BC
|
||||
@@ -215,14 +227,18 @@ MLDDLY: ADD A,C
|
||||
POP AF
|
||||
RET
|
||||
|
||||
|
||||
;
|
||||
; Method to sound the bell, basically play a constant tone.
|
||||
;
|
||||
?BEL: PUSH DE
|
||||
LD DE,00DB1H
|
||||
CALL ?MLDY
|
||||
POP DE
|
||||
RET
|
||||
|
||||
|
||||
;
|
||||
; Melody (note) lookup table.
|
||||
;
|
||||
MTBL: DB 043H
|
||||
DB 077H
|
||||
DB 007H
|
||||
@@ -282,6 +298,137 @@ OPTBL: DB 001H
|
||||
DB 010H
|
||||
DB 018H
|
||||
DB 020H
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF AUDIO CONTROLLER FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF RTC FUNCTIONALITY (INTR HANDLER IN MAIN CBIOS)
|
||||
;-------------------------------------------------------------------------------
|
||||
;
|
||||
; BC:DE:HL contains the time in milliseconds (100msec resolution) since 01/01/1980. In IX is held the interrupt service handler routine address for the RTC.
|
||||
; HL contains lower 16 bits, DE contains middle 16 bits, BC contains upper 16bits, allows for a time from 00:00:00 to 23:59:59, for > 500000 days!
|
||||
?TIMESET: DI
|
||||
;
|
||||
LD (TIMESEC),HL ; Load lower 16 bits.
|
||||
EX DE,HL
|
||||
LD (TIMESEC+2),HL ; Load middle 16 bits.
|
||||
PUSH BC
|
||||
POP HL
|
||||
LD (TIMESEC+4),HL ; Load upper 16 bits.
|
||||
;
|
||||
LD HL,CONTF
|
||||
LD (HL),074H ; Set Counter 1, read/load lsb first then msb, mode 2 rate generator, binary
|
||||
LD (HL),0B0H ; Set Counter 2, read/load lsb first then msb, mode 0 interrupt on terminal count, binary
|
||||
DEC HL
|
||||
LD DE,TMRTICKINTV ; 100Hz coming into Timer 2 from Timer 1, set divisor to set interrupts per second.
|
||||
LD (HL),E ; Place current time in Counter 2
|
||||
LD (HL),D
|
||||
DEC HL
|
||||
LD (HL),03BH ; Place divisor in Counter 1, = 315, thus 31500/315 = 100
|
||||
LD (HL),001H
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
;
|
||||
LD A, 0C3H ; Install the interrupt vector for when interrupts are enabled.
|
||||
LD (00038H),A
|
||||
LD (00039H),IX
|
||||
;EI
|
||||
RET
|
||||
|
||||
; Time Read;
|
||||
; Returns BC:DE:HL where HL is lower 16bits, DE is middle 16bits and BC is upper 16bits of milliseconds since 01/01/1980.
|
||||
?TIMEREAD: LD HL,(TIMESEC+4)
|
||||
PUSH HL
|
||||
POP BC
|
||||
LD HL,(TIMESEC+2)
|
||||
EX DE,HL
|
||||
LD HL,(TIMESEC)
|
||||
RET
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF RTC FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF KEYBOARD FUNCTIONALITY (INTR HANDLER SEPERATE IN CBIOS)
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
?MODE: LD HL,KEYPF
|
||||
LD (HL),08AH
|
||||
LD (HL),007H
|
||||
LD (HL),005H
|
||||
LD (HL),001H
|
||||
RET
|
||||
|
||||
; Method to check if a key has been pressed and stored in buffer..
|
||||
?CHKKY: LD A, (KEYCOUNT)
|
||||
OR A
|
||||
JR Z,CHKKY2
|
||||
LD A,0FFH
|
||||
RET
|
||||
CHKKY2: XOR A
|
||||
RET
|
||||
|
||||
?GETKY: PUSH HL
|
||||
LD A,(KEYCOUNT)
|
||||
OR A
|
||||
JR Z,GETKY2
|
||||
GETKY1: DI ; Disable interrupts, we dont want a race state occurring.
|
||||
LD A,(KEYCOUNT)
|
||||
DEC A ; Take 1 off the total count as we are reading a character out of the buffer.
|
||||
LD (KEYCOUNT),A
|
||||
LD HL,(KEYREAD) ; Get the position in the buffer where the next available character resides.
|
||||
LD A,(HL) ; Read the character and save.
|
||||
PUSH AF
|
||||
INC L ; Update the read pointer and save.
|
||||
LD A,L
|
||||
AND KEYBUFSIZE-1
|
||||
LD L,A
|
||||
LD (KEYREAD),HL
|
||||
POP AF
|
||||
EI ; Interrupts back on so keys and RTC are actioned.
|
||||
JR ?PRCKEY ; Process the key, action any non ASCII keys.
|
||||
;
|
||||
GETKY2: LD A,(KEYCOUNT) ; No key available so loop until one is.
|
||||
OR A
|
||||
JR Z,GETKY2
|
||||
JR GETKY1
|
||||
;
|
||||
?PRCKEY: CP CR ; CR
|
||||
JR NZ,?PRCKY3
|
||||
JR ?PRCKYE
|
||||
?PRCKY3: CP HOMEKEY ; HOME
|
||||
JR NZ,?PRCKY4
|
||||
JR GETKY2
|
||||
?PRCKY4: CP CLRKEY ; CLR
|
||||
JR NZ,?PRCKY5
|
||||
JR GETKY2
|
||||
?PRCKY5: CP INSERT ; INSERT
|
||||
JR NZ,?PRCKY6
|
||||
JR GETKY2
|
||||
?PRCKY6: CP DBLZERO ; 00
|
||||
JR NZ,?PRCKY7
|
||||
LD A,'0'
|
||||
LD (KEYBUF),A ; Place a character into the keybuffer so we double up on 0
|
||||
JR ?PRCKYX
|
||||
?PRCKY7: CP BREAKKEY ; Break key processing.
|
||||
JR NZ,?PRCKY8
|
||||
|
||||
?PRCKY8:
|
||||
?PRCKYX:
|
||||
?PRCKYE:
|
||||
POP HL
|
||||
RET
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF KEYBOARD FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
ALIGN_NOPS UROMADDR + 0800h
|
||||
|
||||
|
||||
@@ -45,12 +45,17 @@
|
||||
NOP
|
||||
; After switching in Bank 0, it will automatically continue processing in Bank 0 at the XOR A instructionof ROMFS:
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Jump table for entry into this pages functions.
|
||||
;-------------------------------------------------------------------------------
|
||||
JP ?PRNT ; 9 QPRNT
|
||||
JP ?PRTHX ; 12 QPRTHX
|
||||
JP ?PRTHL ; 15 QPRTHL
|
||||
JP ?ANSITERM ; 18 QANSITERM
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF SCREEN FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; CR PAGE MODE1
|
||||
.CR: CALL .MANG
|
||||
@@ -105,51 +110,6 @@ DPCT1: ADD HL,BC
|
||||
EX DE,HL
|
||||
JP (HL)
|
||||
|
||||
;?SAVE: LD HL,FLSDT
|
||||
; LD A,(SFTLK)
|
||||
; OR A
|
||||
; LD (HL),043H ; Thick block cursor when lower case.
|
||||
; JR Z,SAVE1
|
||||
; CP 1
|
||||
; LD (HL),03EH ; Thick underscore when CAPS lock.
|
||||
; JR Z,SAVE1
|
||||
; LD (HL),0EFH ; Block cursor when SHIFT lock.
|
||||
;SAVE1: LD A,(HL)
|
||||
; PUSH AF
|
||||
; CALL ?PONT
|
||||
; LD A,(HL)
|
||||
; LD (FLASH),A
|
||||
; POP AF
|
||||
; LD (HL),A
|
||||
; XOR A
|
||||
; LD HL,KEYPA
|
||||
; LD (HL),A
|
||||
; CPL
|
||||
; LD (HL),A
|
||||
; RET
|
||||
;
|
||||
;?LOAD: PUSH AF
|
||||
; LD A,(FLASH)
|
||||
; CALL ?PONT
|
||||
; LD (HL),A
|
||||
; POP AF
|
||||
; RET
|
||||
;
|
||||
;?FLAS: PUSH AF
|
||||
; PUSH HL
|
||||
; LD A,(KEYPC)
|
||||
; RLCA
|
||||
; RLCA
|
||||
; JR C,FLAS1
|
||||
; LD A,(FLSDT)
|
||||
;FLAS2: CALL ?PONT
|
||||
; LD (HL),A
|
||||
;FLAS3: POP HL
|
||||
; POP AF
|
||||
; RET
|
||||
;FLAS1: LD A,(FLASH)
|
||||
; JR FLAS2
|
||||
|
||||
|
||||
?PRT: LD A,C
|
||||
CALL ?ADCN
|
||||
@@ -860,6 +820,9 @@ ATBL: DB 0CCH ; NUL '\0' (null character)
|
||||
DB 0CBH
|
||||
DB 000H
|
||||
DB 01EH
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF SCREEN FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
;----------------------------------------
|
||||
;
|
||||
@@ -1470,6 +1433,10 @@ RCP: LD HL,(CURSORPSAV) ; (curr
|
||||
LD (DSPXY),HL
|
||||
JP ANSIEXIT
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF ANSI TERMINAL FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
ALIGN_NOPS UROMADDR + 0800h
|
||||
|
||||
; Bring in additional macros.
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
;- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
;======================================
|
||||
;============================================================
|
||||
;
|
||||
; USER ROM CPM CBIOS BANK 3
|
||||
; USER ROM CPM CBIOS BANK 3 - SD Card Controller functions.
|
||||
;
|
||||
;======================================
|
||||
;============================================================
|
||||
ORG UROMADDR
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
@@ -44,7 +44,702 @@
|
||||
NOP
|
||||
; After switching in Bank 0, it will automatically continue processing in Bank 0 at the XOR A instructionof ROMFS:
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Jump table for entry into this pages functions.
|
||||
;-------------------------------------------------------------------------------
|
||||
JP ?SD_INIT ; 9 SD_INIT
|
||||
JP ?SD_READ ; 12 SD_READ
|
||||
JP ?SD_WRITE ; 15 SD_WRITE
|
||||
JP ?SD_GETLBA ; 18 SD_GETLBA
|
||||
JP ?SDC_READ ; 21 SDC_READ
|
||||
JP ?SDC_WRITE ; 24 SDC_WRITE
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF SD CARD CONTROLLER FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; Method to initialise the SD card.
|
||||
;
|
||||
?SD_INIT: LD A,000H ; CS to high
|
||||
CALL SPICS
|
||||
;
|
||||
CALL SPIINIT ; Train SD with our clock.
|
||||
;
|
||||
LD A,0FFH ; CS to low
|
||||
CALL SPICS
|
||||
|
||||
LD BC,0FFFFH
|
||||
SD_INIT1: LD A,CMD0 ; Command 0
|
||||
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
|
||||
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
|
||||
CALL SDCMD
|
||||
|
||||
PUSH BC
|
||||
LD A,(SDBUF+6) ; Get response code.
|
||||
DEC A ; Set Z flag to test if response is 0x01
|
||||
JP Z,SD_INIT2 ; Command response 0x01? Exit if match.
|
||||
POP BC
|
||||
DEC BC
|
||||
LD A,B
|
||||
OR C
|
||||
JR NZ,SD_INIT1 ; Retry for BC times.
|
||||
LD A,1
|
||||
JP SD_EXIT ; Error, card is not responding to CMD0
|
||||
SD_INIT2: POP BC
|
||||
; Now send CMD8 to get card details. This command can only be sent
|
||||
; when the card is idle.
|
||||
LD A,CMD8 ; CMD8 has 0x00001AA as parameter, load up registers and call command routine.
|
||||
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
|
||||
LD DE,0AA01H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
|
||||
CALL SDCMD
|
||||
|
||||
; Version 2 card, check its voltage range. IF not in the 2.7-3.6V dont try the ACMD41 to get capabilities.
|
||||
SD_INIT3: LD A,1 ; Check that we receive 0x0001AA in response.
|
||||
LD (SDVER),A ; Indicate this is not a version 2 card.
|
||||
LD A,(SDBUF+9)
|
||||
CP 1
|
||||
JP NZ,SD_INIT8
|
||||
LD A,(SDBUF+10)
|
||||
CP 0AAH
|
||||
JP NZ,SD_INIT8
|
||||
|
||||
SD_INIT4: LD A,2 ; This is a version 2 card.
|
||||
SD_INIT5: LD (SDVER),A ; Indicate this is not a version 2 card.
|
||||
|
||||
CALL SDACMD41
|
||||
JR Z,SD_INIT6
|
||||
LD A,2 ; Error, card is not responding to ACMD41
|
||||
JP SD_EXIT
|
||||
|
||||
SD_INIT6: LD A,CMD58 ; CMD58 has 0x00000000 as parameter, load up registers and call command routine.
|
||||
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
|
||||
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
|
||||
CALL SDCMD
|
||||
LD A,(SDBUF+6)
|
||||
CP 040H
|
||||
LD A,CT_SD2
|
||||
JR Z,SD_INIT7
|
||||
LD A,CT_SD2 | CT_BLOCK
|
||||
SD_INIT7: LD (SDCAP),A ; Set the capabilities according to the returned flag.
|
||||
JR SD_INIT14
|
||||
|
||||
|
||||
; Version 1 card or MMC v3.
|
||||
SD_INIT8: CALL SDACMD41
|
||||
LD A, CT_SD1
|
||||
LD E,ACMD41 ; SD1 cards we use the ACMD41 command.
|
||||
JR Z,SD_INIT9
|
||||
LD A,CT_MMC
|
||||
LD E,CMD1 ; MMC cards we use the CMD1 command.
|
||||
SD_INIT9: LD (SDCAP),A
|
||||
LD A,E
|
||||
CP ACMD41
|
||||
JR NZ,SD_INIT10
|
||||
CALL SDACMD41
|
||||
JR Z,SD_INIT14
|
||||
LD A,3 ; Exit code, failed to initialise v1 card.
|
||||
JR SD_EXIT
|
||||
|
||||
SD_INIT10: LD BC,10 ; ACMD41/CMD55 may take some cards time to process or respond, so give a large number of retries.
|
||||
SD_INIT11: PUSH BC
|
||||
LD A,CMD1 ; CMD1 has 0x00000000 as parameter, load up registers and call command routine.
|
||||
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
|
||||
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
|
||||
CALL SDCMD
|
||||
LD A,(SDBUF+6) ; Should be a response of 0 whereby the card has left idle.
|
||||
OR A
|
||||
JR Z,SD_INIT13
|
||||
LD BC,0FFFFH ; Delay for at least 200mS for the card to recover and be ready.
|
||||
SD_INIT12: DEC BC ; 6T
|
||||
LD A,B ; 9T
|
||||
OR C ; 4T
|
||||
JR NZ,SD_INIT12 ; 12T = 31T x 500ns = 15.5uS x 12903 = 200mS
|
||||
;
|
||||
POP BC
|
||||
DEC BC
|
||||
LD A,B
|
||||
OR C
|
||||
JR NZ,SD_INIT11
|
||||
LD A,4 ; Exit code, failed to initialise v1 MMC card.
|
||||
JR SD_EXIT
|
||||
|
||||
SD_INIT13: LD A,CMD16 ; No response from the card for an ACMD41/CMD1 so try CMD16 with parameter 0x00000200
|
||||
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
|
||||
LD DE,00002H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
|
||||
CALL SDCMD
|
||||
LD A,(SDBUF+6)
|
||||
OR A
|
||||
JR Z,SD_INIT14
|
||||
LD A,0
|
||||
LD (SDCAP),A ; No capabilities on this unknown card.
|
||||
SD_INIT14: XOR A
|
||||
SD_EXIT: OR A ; Return value is in A.
|
||||
RET
|
||||
|
||||
; Method to initialise communications with the SD card. We basically train it to our clock characteristics.
|
||||
; This is important, as is maintaining the same clock for read or write otherwise the card may not respond.
|
||||
SPIINIT: LD B,80
|
||||
SPIINIT1: LD A,DOUT_HIGH | CLOCK_HIGH | CS_HIGH ; Output a 1
|
||||
OUT (SPI_OUT),A
|
||||
LD A,DOUT_HIGH | CLOCK_LOW | CS_HIGH ; Output a 1
|
||||
OUT (SPI_OUT),A
|
||||
DJNZ SPIINIT1
|
||||
RET
|
||||
|
||||
; Method to set the Chip Select level on the SD card. The Chip Select is active LOW.
|
||||
;
|
||||
; A = 0 - Set CS HIGH
|
||||
; A = 0xFF - Set CS LOW
|
||||
SPICS: OR A
|
||||
LD A,DOUT_HIGH | CLOCK_LOW | CS_HIGH ; Set CS High if parameter = 0 (ie. disable)
|
||||
JR Z, SPICS0
|
||||
LD A,DOUT_HIGH | CLOCK_LOW | CS_LOW ; Set CS Low if parameter != 0 (ie. disable)
|
||||
SPICS0: OUT (SPI_OUT),A
|
||||
RET
|
||||
|
||||
; Method to send a command to the card and receive back a response.
|
||||
;
|
||||
; A = CMD to send
|
||||
; LHED = Argument, ie. CMD = A, L, H, E, D, CRC
|
||||
;
|
||||
SDCMD: LD (SDBUF),A
|
||||
LD (SDBUF+1),HL
|
||||
EX DE,HL
|
||||
LD (SDBUF+3),HL
|
||||
;
|
||||
; Send command but with parameters preloaded by caller.
|
||||
SDCMDNP: LD B,5 ; R1 + 32bit argument for CMD8, CMD58
|
||||
CP CMD8
|
||||
LD C,135
|
||||
JP Z,SDCMD0
|
||||
LD C,1 ; CMD58 is not CRC checked so just set to 0x01.
|
||||
CP CMD58
|
||||
LD B,5 ; R1 + 32bit argument
|
||||
JP Z,SDCMD0
|
||||
;
|
||||
LD B,1 ; Default, expect R1 which is 1 byte.
|
||||
CP CMD0 ; Work out the CRC based on the command. CRC checking is
|
||||
LD C,149 ; not implemented but certain commands require a fixed argument and CRC.
|
||||
JP Z,SDCMD0
|
||||
LD C,1 ; Remaining commands are not CRC checked so just set to 0x01.
|
||||
SDCMD0: PUSH BC ; Save the CRC and the number of bytes to be returned,
|
||||
LD A,C ; Store the CRC
|
||||
LD (SDBUF+5),A
|
||||
LD A,255 ; Preamble byte
|
||||
CALL SPIOUT
|
||||
LD HL,SDBUF
|
||||
LD B,6
|
||||
SDCMD1: PUSH BC
|
||||
LD A,(HL)
|
||||
INC HL
|
||||
CALL SPIOUT ; Send the command and parameters.
|
||||
POP BC
|
||||
DJNZ SDCMD1
|
||||
PUSH HL
|
||||
SDCMD2: CALL SPIIN
|
||||
CP 0FFH
|
||||
JR Z,SDCMD2
|
||||
JR SDCMD4
|
||||
SDCMD3: PUSH BC
|
||||
PUSH HL
|
||||
CALL SPIIN ;
|
||||
SDCMD4: POP HL
|
||||
LD (HL),A
|
||||
INC HL
|
||||
POP BC ; Get back number of expected bytes. HL = place in buffer to store response.
|
||||
DJNZ SDCMD3
|
||||
LD A,DOUT_HIGH | CLOCK_LOW | CS_HIGH
|
||||
OUT (SPI_OUT),A
|
||||
RET
|
||||
|
||||
; Method to send an Application Command to the SD Card. This involves sending CMD55 followed by the required command.
|
||||
;
|
||||
; A = ACMD to send
|
||||
; LHED = Argument, ie. ACMD = A, L, H, E, D, CRC
|
||||
;
|
||||
SDACMD: PUSH AF
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
LD A,CMD55 ; CMD55 has 0x00000000 as parameter, load up registers and call command routine.
|
||||
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
|
||||
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
|
||||
CALL SDCMD
|
||||
POP HL
|
||||
POP DE
|
||||
LD A,(SDBUF+6) ; Should be a response of 0 or 1.
|
||||
CP 2
|
||||
JR NC,SDACMD0
|
||||
POP AF
|
||||
CALL SDCMD
|
||||
LD A,(SDBUF+6) ; Should be a response of 0 whereby the card has left idle.
|
||||
OR A
|
||||
RET
|
||||
SDACMD0: POP AF
|
||||
CP 1
|
||||
RET
|
||||
|
||||
; Method to send Application Command 41 to the SD card. This command involves retries and delays
|
||||
; hence coded seperately.
|
||||
;
|
||||
; Returns Z set if successful, else NZ.
|
||||
;
|
||||
SDACMD41: LD BC,10 ; ACMD41/CMD55 may take some cards time to process or respond, so give a large number of retries.
|
||||
SDACMD1: PUSH BC
|
||||
LD A,ACMD41 ; ACMD41 has 0x40000000 as parameter, load up registers and call command routine.
|
||||
LD HL,00040H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
|
||||
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
|
||||
CALL SDACMD
|
||||
JR Z,SDACMD3 ; Should be a response of 0 whereby the card has left idle.
|
||||
LD BC,12903 ; Delay for at least 200mS for the card to recover and be ready.
|
||||
SDACMD2: DEC BC ; 6T
|
||||
LD A,B ; 9T
|
||||
OR C ; 4T
|
||||
JR NZ,SDACMD2 ; 12T = 31T x 500ns = 15.5uS x 12903 = 200mS
|
||||
;
|
||||
POP BC
|
||||
DEC BC
|
||||
LD A,B
|
||||
OR C
|
||||
JR NZ,SDACMD1
|
||||
LD A,1 ; Retries exceeded, return error.
|
||||
OR A
|
||||
RET
|
||||
SDACMD3: POP BC ; Success, tidy up stack and exit with Z set.
|
||||
XOR A
|
||||
RET
|
||||
|
||||
; Method to send a byte to the SD card via the SPI protocol.
|
||||
; This method uses the bitbang technique, change if hardware spi is available.
|
||||
;
|
||||
; Input A = Byte to send.
|
||||
;
|
||||
SPIOUT: RLCA ; 65432107
|
||||
RLCA ; 54321076
|
||||
RLCA ; 43210765 - Adjust so that starting bit is same position as Data line.
|
||||
LD E,A ; E = Character to send.
|
||||
LD B,8 ; B = Bit count
|
||||
SPIOUT0: LD A,E
|
||||
AND DOUT_MASK ; Data bit to data line, clock and cs low.
|
||||
RLC E
|
||||
SPIOUT1: OUT (SPI_OUT),A
|
||||
OR CLOCK_HIGH ; Clock high
|
||||
OUT (SPI_OUT),A
|
||||
AND CLOCK_MASK ; Clock low
|
||||
OUT (SPI_OUT),A
|
||||
DJNZ SPIOUT0 ; Perform actions for the full 8 bits.
|
||||
RET
|
||||
|
||||
; Method to receive a byte from the SD card via the SPI protocol.
|
||||
; This method uses the bitbang technique, change if hardware spi is available.
|
||||
; NB. Timing must be very similar in SPIOUT and SPIIN.
|
||||
;
|
||||
; Output: A = received byte.
|
||||
;
|
||||
SPIIN: LD BC,00800H | SPI_OUT ; B = Bit count, C = clock port
|
||||
LD L,0 ; L = Character being read.
|
||||
LD D,DOUT_HIGH | CLOCK_LOW | CS_LOW ; Output a 0
|
||||
OUT (C),D ; To start ensure clock is low and CS is low.
|
||||
LD E,DOUT_HIGH | CLOCK_HIGH | CS_LOW ; Output a 0
|
||||
SPIIN1: OUT (C),E ; Clock to high.
|
||||
IN A,(SPI_IN) ; Input the received bit
|
||||
OUT (C),D ; Clock to low.
|
||||
SRL A
|
||||
RL L
|
||||
DJNZ SPIIN1 ; Perform actions for the full 8 bits.
|
||||
LD A,L ; return value
|
||||
RET
|
||||
|
||||
; A function from the z88dk stdlib, a delay loop with T state accuracy.
|
||||
;
|
||||
; enter : hl = tstates >= 141
|
||||
; uses : af, bc, hl
|
||||
T_DELAY: LD BC,-141
|
||||
ADD HL,BC
|
||||
LD BC,-23
|
||||
TDELAYLOOP: ADD HL,BC
|
||||
JR C, TDELAYLOOP
|
||||
LD A,L
|
||||
ADD A,15
|
||||
JR NC, TDELAYG0
|
||||
CP 8
|
||||
JR C, TDELAYG1
|
||||
OR 0
|
||||
TDELAYG0: INC HL
|
||||
TDELAYG1: RRA
|
||||
JR C, TDELAYB0
|
||||
NOP
|
||||
TDELAYB0: RRA
|
||||
JR NC, TDELAYB1
|
||||
OR 0
|
||||
TDELAYB1: RRA
|
||||
RET NC
|
||||
RET
|
||||
|
||||
; Method to skip over an SD card input stream to arrive at the required bytes,
|
||||
;
|
||||
; Input: BC = Number of bytes to skip.
|
||||
;
|
||||
SPISKIP: PUSH BC
|
||||
CALL SPIIN
|
||||
POP BC
|
||||
DEC BC
|
||||
LD A,B
|
||||
OR C
|
||||
JR NZ,SPISKIP
|
||||
RET
|
||||
|
||||
; Method to convert an LBA value into a physical byte address. This is achieved by multiplying the block x 512.
|
||||
; We take the big endian sector value, shift left 9 times then store the result back onto the stack.
|
||||
; This is done as follows: <MSB> <2> <1> <0> => <2> <1> <0> 0 (ie. 8 bit shift): Shift left <0> with carry, shift left <1> shift left <2>, 0 to <LSB>
|
||||
;
|
||||
; Input: HL = Stack offset.
|
||||
;
|
||||
LBATOADDR: LD HL,(SDSTARTSEC+1)
|
||||
LD A,(HL) ; Start ny retrieving bytes as HED0
|
||||
INC HL
|
||||
LD E,(HL)
|
||||
INC HL
|
||||
LD D,(HL)
|
||||
LD L,A
|
||||
|
||||
SLA D ; Shift the long left by 9 to effect a x512
|
||||
RL E
|
||||
RL H
|
||||
LD BC,(SDSTARTSEC)
|
||||
LD A,H ; Now save the results as LHED, big endian format as used by the SD Card argument
|
||||
LD (BC),A
|
||||
INC BC
|
||||
LD A,E
|
||||
LD (BC),A
|
||||
INC BC
|
||||
LD A,D
|
||||
LD (BC),A
|
||||
INC BC
|
||||
LD A,0
|
||||
LD (BC),A
|
||||
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: 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.
|
||||
; Output: A = 0 - All ok. A > 0 - error occurred.
|
||||
;
|
||||
?SD_READ: PUSH HL ; Store the load address.
|
||||
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_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_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
|
||||
LD HL,(SDSTARTSEC)
|
||||
LD (SDBUF+1),HL
|
||||
LD HL,(SDSTARTSEC+2)
|
||||
LD (SDBUF+3),HL
|
||||
CALL SDCMDNP ; Execute SD Command, parameters already loaded into command buffer.
|
||||
LD A,(SDBUF+6) ; Fetch result and store.
|
||||
AND A
|
||||
JP NZ,SD_READ6
|
||||
|
||||
LD HL,1000 ; Sit in a tight loop waiting for the data packet arrival (ie. not 0xFF).
|
||||
SD_READ2: PUSH HL
|
||||
LD HL,200
|
||||
CALL T_DELAY
|
||||
CALL SPIIN
|
||||
POP HL
|
||||
CP 255
|
||||
JP NZ,SD_READ3
|
||||
DEC HL
|
||||
LD A,H
|
||||
OR L
|
||||
JR NZ,SD_READ2
|
||||
|
||||
SD_READ3: CP 254 ; Data? If not exit with error code.
|
||||
JP NZ,SD_READ6
|
||||
|
||||
LD BC,SD_SECSIZE ; Size of full sector + 2 bytes CRC.
|
||||
POP HL ; Get the store address into HL.
|
||||
SD_READ4: PUSH HL ; Start reading bytes into the buffer.
|
||||
PUSH BC
|
||||
CALL SPIIN
|
||||
POP BC
|
||||
POP HL
|
||||
LD (HL),A
|
||||
INC HL ; Update buffer pointer.
|
||||
DEC BC
|
||||
LD A,B
|
||||
OR C
|
||||
JP NZ,SD_READ4 ; Not zero, keep reading.
|
||||
|
||||
INC BC ; Were not interested in the CRC so skip it.
|
||||
INC BC
|
||||
CALL SPISKIP
|
||||
|
||||
LD A,0 ; And exit with success.
|
||||
SD_READ5: PUSH AF
|
||||
LD A,0
|
||||
CALL SPICS
|
||||
POP AF
|
||||
RET
|
||||
SD_READ6: POP HL
|
||||
LD A,1
|
||||
JR SD_READ5
|
||||
|
||||
|
||||
; Method to write a 512byte sector to an SD Card.
|
||||
;
|
||||
; 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 of buffer to read data from.
|
||||
; Output: A = 0 - All ok. A > 0 - error occurred.
|
||||
?SD_WRITE: PUSH HL
|
||||
|
||||
LD A,0FFH ; Activate CS (set low).
|
||||
CALL SPICS
|
||||
|
||||
; 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_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_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
|
||||
LD HL,(SDSTARTSEC+2)
|
||||
LD (SDBUF+3),HL
|
||||
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_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
|
||||
|
||||
; Write buffer.
|
||||
LD DE,SD_SECSIZE
|
||||
POP HL ; Address to read data from.
|
||||
SD_WRITE2: LD A,D ; So long as we have bytes in the buffer, send to the card for writing.
|
||||
OR E
|
||||
JP Z,SD_WRITE3
|
||||
|
||||
PUSH DE
|
||||
LD A,(HL) ; Get the byte to transmit.
|
||||
INC HL ; And update the pointer.
|
||||
CALL SPIOUT ; Transmit value in A.
|
||||
POP DE
|
||||
DEC DE
|
||||
JR SD_WRITE2
|
||||
|
||||
; Close transaction.
|
||||
SD_WRITE3: INC DE ; Add 2 bytes for CRC
|
||||
INC DE
|
||||
SD_WRITE4: LD A,D ; Test to see if we are already at zero, ie. all bytes sent. Exit if so.
|
||||
OR E
|
||||
JP Z,SD_WRITE5
|
||||
DEC DE
|
||||
PUSH DE
|
||||
LD A,0 ; Send 0's as padding bytes and CRC.
|
||||
CALL SPIOUT
|
||||
POP DE
|
||||
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_WRITE11
|
||||
|
||||
LD HL,10000 ; Now wait for the write to complete allowing 1000mS before timing out.
|
||||
PUSH 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_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_WRITE8
|
||||
LD A,H
|
||||
OR L
|
||||
JR NZ,SD_WRITE6
|
||||
|
||||
SD_WRITE8: LD A,H ; End of timeout? If so we exit with the preset fail code.
|
||||
OR L
|
||||
JP Z,SD_WRITE11
|
||||
XOR A ; Success code.
|
||||
|
||||
SD_WRITE9: PUSH AF
|
||||
LD A,000H ; Disable SD Card Chip Select to finish.
|
||||
CALL SPICS
|
||||
POP AF
|
||||
RET
|
||||
SD_WRITE10: POP HL ; Waste the load address.
|
||||
SD_WRITE11: LD A,1 ; Error exit.
|
||||
JR SD_WRITE9
|
||||
|
||||
|
||||
|
||||
; 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
|
||||
|
||||
; Method to get the LBA sector from the current CP/M Track and Sector.
|
||||
; This method needs to account for the Rom Filing System image and the other CPM disk images on the SD card.
|
||||
;
|
||||
; Input: (CDISK) = Disk number
|
||||
; (HSTTRK) = Track
|
||||
; (HSTSEC) = Sector
|
||||
; Output: (SDSTARTSEC) = LBA on SD Card for the desired sector.
|
||||
; DEHL = LBA on SD Card for the desired sector.
|
||||
;
|
||||
?SD_GETLBA: PUSH AF ; If needed, pass A and flags via the stack. NB This push is removed by BANKTOBANK so no need to pop after the call.
|
||||
LD A,ROMBANK11 << 4 | ROMBANK10 ; Calling a function in Bank 11 (CBIOS Bank 4) and returning to current bank 10 (CBIOS Bank 3).
|
||||
LD HL,QGETMAPDSK ; Calling the map disk function.
|
||||
CALL BANKTOBANK ; Now make a bank to bank function call.
|
||||
CP 0FFH
|
||||
JR Z,SDGETLBAX ; This isnt a physical, ROM disk or SD disk, no need to perform any actions, exit.
|
||||
CP 040H
|
||||
JR C,SDGETLBAX ; This isnt a ROM disk or an SD disk, no need to perform any actions, exit.
|
||||
AND 03FH ; Get the SD disk number.
|
||||
|
||||
LD B,0
|
||||
LD C,A
|
||||
LD DE,CPM_SD_IMGSZ / SD_SECSIZE
|
||||
CALL MULT16X16
|
||||
LD (SDSTARTSEC),DE
|
||||
LD (SDSTARTSEC+2),HL
|
||||
|
||||
; DEHL contains the offset for the Disk number, ie. 0 for drive 1, CPM IMAGE SIZE for drive 2, 2x CPM IMAGE SIZE for drive 3 etc.
|
||||
LD B,0
|
||||
LD C, SD_SECPTRK ; Number of sectors per track.
|
||||
LD DE,(HSTTRK) ; For the SD Card we use the full 16bit track number.
|
||||
CALL MULT16X16
|
||||
|
||||
; Add the two.
|
||||
CALL ADD32
|
||||
|
||||
; Add the number of sectors directly to the current sum.
|
||||
LD A,(HSTSEC)
|
||||
LD C,A
|
||||
LD B,0
|
||||
CALL ADD3216
|
||||
|
||||
; Now add the offset to account for the RFS image.
|
||||
LD BC, RFS_IMGSZ/SD_SECSIZE ; Sector offset for the RFS Image.
|
||||
CALL ADD3216
|
||||
|
||||
; Store the final sum as the start sector.
|
||||
PUSH HL
|
||||
LD HL,SDSTARTSEC
|
||||
LD (HL),D
|
||||
INC HL
|
||||
LD (HL),E
|
||||
INC HL
|
||||
POP DE
|
||||
LD (HL),D
|
||||
INC HL
|
||||
LD (HL),E
|
||||
LD HL,(SDSTARTSEC)
|
||||
OR 1 ; Indicate we successfully mapped the track/sector to an LBA.
|
||||
SDGETLBAX: RET
|
||||
|
||||
|
||||
; Method to read a sector for CPM using its track/sector addressing. All reads occur in a 512byte sector.
|
||||
;
|
||||
; Inputs: (HSTTRK) - 16bit track number.
|
||||
; (HSTSEK) - 8bit sector number.
|
||||
; (CDISK) - Disk drive number.
|
||||
?SDC_READ: CALL ?SD_GETLBA ; Get the SD card sector in LBA,
|
||||
LD A,1
|
||||
JP Z,SDC_READ1 ; Error in read, exit with stack tidy.
|
||||
LD HL,HSTBUF ; Address of the host buffer to hold the sector.
|
||||
CALL ?SD_READ ; Read in the sector.
|
||||
OR A
|
||||
JR NZ,SDC_READ1 ; Check for errors and report.
|
||||
XOR A ; Indicate success.
|
||||
SDC_READ1: RET
|
||||
|
||||
; Method to write a sector for CPM using its track/sector addressing. All writes occur in a 512byte sector.
|
||||
;
|
||||
; Inputs: (HSTTRK) - 16bit track number.
|
||||
; (HSTSEK) - 8bit sector number.
|
||||
; (CDISK) - Disk drive number.
|
||||
; Outputs: A = 1 - Error.
|
||||
; A = 0 - Success.
|
||||
?SDC_WRITE: CALL ?SD_GETLBA ; Get the SD card sector in LBA,
|
||||
LD A,1
|
||||
JP Z,SDC_WRITE1 ; Error in read, exit with stack tidy.
|
||||
LD HL,HSTBUF ; Setup the location of the buffer to write.
|
||||
CALL ?SD_WRITE ; Call write to write the buffer into the given sector.
|
||||
JR NZ,SDC_WRITE1
|
||||
XOR A
|
||||
SDC_WRITE1: RET
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF SD CARD CONTROLLER FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
ALIGN_NOPS UROMADDR + 0800h
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
;- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
;======================================
|
||||
;============================================================
|
||||
;
|
||||
; USER ROM CPM CBIOS BANK 4
|
||||
; USER ROM CPM CBIOS BANK 4 - Floppy Disk Controller functions.
|
||||
;
|
||||
;======================================
|
||||
;============================================================
|
||||
ORG UROMADDR
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
@@ -44,9 +44,562 @@
|
||||
NOP
|
||||
; After switching in Bank 0, it will automatically continue processing in Bank 0 at the XOR A instructionof ROMFS:
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Jump table for entry into this pages functions.
|
||||
;-------------------------------------------------------------------------------
|
||||
JP ?DSKINIT ; 9 DSKINIT
|
||||
JP ?SETDRVCFG ; 12 SETDRVCFG
|
||||
JP ?SETDRVMAP ; 15 SETDRVMAP
|
||||
JP ?SELDRIVE ; 18 SELDRIVE
|
||||
JP ?GETMAPDSK ; 21 GETMAPDSK
|
||||
JP ?DSKREAD ; 24 DSKREAD
|
||||
JP ?DSKWRITE ; 24 DSKWRITE
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF FDC CONTROLLER FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
;------------------------------------------------------------------------------------------------
|
||||
; Initialise drive and reset flags, Set motor off
|
||||
;
|
||||
;------------------------------------------------------------------------------------------------
|
||||
?DSKINIT: XOR A
|
||||
OUT (FDC_MOTOR),A ; Motor off
|
||||
LD (TRK0FD1),A ; Track 0 flag drive 1
|
||||
LD (TRK0FD2),A ; Track 0 flag drive 2
|
||||
LD (TRK0FD3),A ; Track 0 flag drive 3
|
||||
LD (TRK0FD4),A ; Track 0 flag drive 4
|
||||
LD (MOTON),A ; Motor on flag
|
||||
LD (MTROFFTIMER),A ; Clear the down counter for motor off.
|
||||
LD A,(FDCROMADDR) ; Check to see if the FDC AFI ROM is installed, use this as
|
||||
OR A ; an indicator that the FDC is present.
|
||||
RET
|
||||
|
||||
; Function to create a mapping table between a CPM disk and a physical disk.
|
||||
?SETDRVMAP: PUSH HL
|
||||
PUSH DE
|
||||
PUSH BC
|
||||
; Zero out the map.
|
||||
LD B,MAXDISKS
|
||||
LD HL,DISKMAP
|
||||
LD A,0FFH
|
||||
SETDRVMAP1: LD (HL),A
|
||||
INC HL
|
||||
DJNZ SETDRVMAP1
|
||||
LD HL,DISKMAP ; Place in the Map for next drive.
|
||||
; Now go through each disk from the Disk Parameter Base list.
|
||||
LD B,0 ; Disk number count = CDISK.
|
||||
LD DE,0 ; Physical disk number, D = FDC, E = SDC.
|
||||
SETDRVMAP2: LD A,B
|
||||
CP MAXDISKS
|
||||
JR Z,SETDRVMAP6
|
||||
INC B
|
||||
PUSH HL
|
||||
PUSH DE
|
||||
PUSH BC
|
||||
; For the Disk in A, find the parameter table.
|
||||
RLC A ; *2
|
||||
RLC A ; *4
|
||||
RLC A ; *8
|
||||
RLC A ; *16
|
||||
LD HL,DPBASE ; Base of disk description block.
|
||||
LD B,0
|
||||
LD C,A
|
||||
ADD HL,BC ; HL contains address of actual selected disk block.
|
||||
LD C,10
|
||||
ADD HL,BC ; HL contains address of pointer to disk parameter block.
|
||||
LD E,(HL)
|
||||
INC HL
|
||||
LD D,(HL) ; DE contains address of disk parameter block.
|
||||
EX DE,HL
|
||||
LD A,(HL)
|
||||
LD E,A
|
||||
LD BC,15
|
||||
ADD HL,BC ; Move to configuuration byte which identifies the disk type.
|
||||
;
|
||||
POP BC
|
||||
POP DE
|
||||
LD A,(HL)
|
||||
POP HL
|
||||
|
||||
BIT 4,A ; Disk type = FDC
|
||||
JR Z,SETDRVMAP4 ; Is this an FDC controlled disk, if so store the mapping number in the map unchanged.
|
||||
;
|
||||
BIT 3,A ; Is this an SD Card disk, if so, add 080H to the mapping number and store.
|
||||
JR Z,SETDRVMAP3
|
||||
LD A,E
|
||||
OR 080H
|
||||
INC E
|
||||
JR SETDRVMAP5
|
||||
SETDRVMAP3: LD A,E ; This is a ROM drive, add 040H to the mapping number and store.
|
||||
OR 040H
|
||||
INC E
|
||||
JR SETDRVMAP5
|
||||
;
|
||||
SETDRVMAP4: LD A,D
|
||||
INC D
|
||||
SETDRVMAP5: LD (HL),A
|
||||
INC HL
|
||||
JR SETDRVMAP2
|
||||
;
|
||||
SETDRVMAP6: POP BC
|
||||
POP DE
|
||||
POP HL
|
||||
RET
|
||||
|
||||
; Function to setup the drive parameters according to the CFG byte in the disk parameter block.
|
||||
?SETDRVCFG: PUSH HL
|
||||
PUSH DE
|
||||
PUSH BC
|
||||
LD A,(CDISK)
|
||||
RLC A ; *2
|
||||
RLC A ; *4
|
||||
RLC A ; *8
|
||||
RLC A ; *16
|
||||
LD HL,DPBASE ; Base of disk description block.
|
||||
LD B,0
|
||||
LD C,A
|
||||
ADD HL,BC ; HL contains address of actual selected disk block.
|
||||
LD C,10
|
||||
ADD HL,BC ; HL contains address of pointer to disk parameter block.
|
||||
LD E,(HL)
|
||||
INC HL
|
||||
LD D,(HL) ; DE contains address of disk parameter block.
|
||||
EX DE,HL
|
||||
LD A,(HL)
|
||||
LD E,A
|
||||
|
||||
LD BC,15
|
||||
ADD HL,BC ; Move to configuuration byte.
|
||||
XOR A
|
||||
BIT 2,(HL)
|
||||
JR Z,SETDRV0
|
||||
INC A
|
||||
SETDRV0: LD (INVFDCDATA),A ; Data inversion is set according to drive parameter.
|
||||
LD A,4
|
||||
BIT 1,(HL)
|
||||
JR Z,SETDRV1
|
||||
LD A,2
|
||||
BIT 0,(HL)
|
||||
JR Z,SETDRV1
|
||||
LD A,1
|
||||
SETDRV1: LD (SECTORCNT),A ; Set the disk sector size.
|
||||
LD D,A
|
||||
CP 4
|
||||
LD A,E
|
||||
JR Z,SETDRV1A
|
||||
OR A
|
||||
RR A
|
||||
LD E,A
|
||||
LD A,D
|
||||
CP 2
|
||||
LD A,E
|
||||
JR Z,SETDRV1A
|
||||
OR A
|
||||
RR A ; Convert sectors per track from 128 bytes to 256 byte sectors.
|
||||
SETDRV1A: INC A ; Add 1 to ease comparisons.
|
||||
LD (SECPERTRK),A ; Only cater for 8bit, ie. 256 sectors.
|
||||
DEC A
|
||||
OR A
|
||||
RR A
|
||||
INC A ; Add 1 to ease comparisons.
|
||||
LD (SECPERHEAD),A ; Convert sectors per track to sectors per head.
|
||||
;
|
||||
XOR A ; Disk type = FDC
|
||||
BIT 4,(HL)
|
||||
JR Z,SETDRV2
|
||||
LD A,DSKTYP_ROM ; Disk type = ROMFS
|
||||
BIT 3,(HL)
|
||||
JR Z,SETDRV2
|
||||
LD A,DSKTYP_SDC ; Disk type = SD Card
|
||||
SETDRV2: LD (DISKTYPE),A
|
||||
POP BC
|
||||
POP DE
|
||||
POP HL
|
||||
RET
|
||||
|
||||
; Method to get the current disk drive mapped to the correct controller.
|
||||
; The CPM CDISK is mapped via MAPDISK[CDISK] and the result:
|
||||
; Bit 7 = 1 - SD Card drive.
|
||||
; Bit 6 = 1 - ROM Drive.
|
||||
; BIT 7:6 = 00 - Floppy drive.
|
||||
?GETMAPDSK: PUSH HL
|
||||
PUSH BC
|
||||
LD A,(CDISK)
|
||||
LD HL,DISKMAP
|
||||
LD C,A
|
||||
LD B,0
|
||||
ADD HL,BC
|
||||
LD A,(HL) ; Get the physical number after mapping from the CDISK.
|
||||
POP BC
|
||||
POP HL
|
||||
RET NC ; This isnt a physical floppy disk, no need to perform any actions, exit.
|
||||
|
||||
; Select FDC drive (make active) based on value in DISKMAP[CDISK].
|
||||
?SELDRIVE: CALL ?GETMAPDSK
|
||||
CP 040H ; Anything with bit 6 or 7 set is not an FDC drive.
|
||||
RET NC ; This isnt a physical floppy disk, no need to perform any actions, exit.
|
||||
LD (FDCDISK),A
|
||||
CALL DSKMTRON ; yes, set motor on and wait
|
||||
LD A,(FDCDISK) ; select drive no
|
||||
OR 084H
|
||||
OUT (FDC_MOTOR),A ; Motor on for drive 0-3
|
||||
XOR A
|
||||
LD (FDCCMD),A ; clr latest FDC command byte
|
||||
LD HL,00000H
|
||||
SELDRV2: DEC HL
|
||||
LD A,H
|
||||
OR L
|
||||
JP Z,SELDRVERR ; Reset and print message that this is not a valid disk.
|
||||
IN A,(FDC_STR) ; Status register.
|
||||
CPL
|
||||
RLCA
|
||||
JR C,SELDRV2 ; Wait on Drive Ready Bit (bit 7)
|
||||
LD A,(FDCDISK) ; Drive number
|
||||
LD C,A
|
||||
LD HL,TRK0FD1 ; 1 track 0 flag for each drive
|
||||
LD B,000H
|
||||
ADD HL,BC ; Compute related flag 1002/1003/1004/1005
|
||||
BIT 0,(HL)
|
||||
JR NZ,SELDRV3 ; If the drive hasnt been intialised to track 0, intialise and set flag.
|
||||
CALL DSKSEEKTK0 ; Seek track 0.
|
||||
SET 0,(HL) ; Set bit 0 of trk 0 flag
|
||||
SELDRV3: CALL ?SETDRVCFG
|
||||
RET
|
||||
|
||||
; Turn disk motor on if not already running.
|
||||
DSKMTRON: LD A,255 ; Ensure motor is kept running whilst we read/write.
|
||||
LD (MTROFFTIMER),A
|
||||
LD A,(MOTON) ; Test to see if motor is on, if it isnt, switch it on.
|
||||
RRCA
|
||||
JR NC, DSKMOTORON
|
||||
RET
|
||||
DSKMOTORON: PUSH BC
|
||||
LD A,080H
|
||||
OUT (FDC_MOTOR),A ; Motor on
|
||||
LD B,010H ;
|
||||
DSKMTR2: CALL MTRDELAY ;
|
||||
DJNZ DSKMTR2 ; Wait until becomes ready.
|
||||
LD A,001H ; Set motor on flag.
|
||||
LD (MOTON),A ;
|
||||
POP BC
|
||||
RET
|
||||
|
||||
FDCDLY1: PUSH DE
|
||||
LD DE,00007H
|
||||
JP MTRDEL2
|
||||
|
||||
MTRDELAY: PUSH DE
|
||||
LD DE,01013H
|
||||
MTRDEL2: DEC DE
|
||||
LD A,E
|
||||
OR D
|
||||
JR NZ,MTRDEL2
|
||||
POP DE
|
||||
RET
|
||||
|
||||
?DSKWRITE: LD A,MAXWRRETRY
|
||||
LD (RETRIES),A
|
||||
LD A,(SECTORCNT)
|
||||
LD B,A
|
||||
LD A,(HSTSEC)
|
||||
DSKWRITE0A: DJNZ DSKWRITE0B
|
||||
JR DSKWRITE1
|
||||
DSKWRITE0B: OR A
|
||||
RL A
|
||||
JR DSKWRITE0A
|
||||
DSKWRITE1: INC A
|
||||
LD (SECTORNO), A ; Convert from Host 512 byte sector into local sector according to paraameter block.
|
||||
LD HL,(HSTTRK)
|
||||
LD (TRACKNO),HL
|
||||
|
||||
DSKWRITE2: CALL SETTRKSEC ; Set current track & sector, get load address to HL
|
||||
DSKWRITE3: CALL SETHEAD ; Set side reg
|
||||
CALL SEEK ; Command 1b output (seek)
|
||||
JP NZ,SEEKRETRY ;
|
||||
CALL OUTTKSEC ; Set track & sector reg
|
||||
|
||||
LD IX, 0F3FEH ; As below. L03FE
|
||||
LD IY,WRITEDATA ; Write sector from memory.
|
||||
DI
|
||||
;
|
||||
LD A,0B4H ; Write Sector multipe with Side Compare for side 1.
|
||||
CALL DISKCMDWAIT
|
||||
LD D,2 ; Regardless of 4x128, 2x256 or 1x512, we always read 512bytes by the 2x INI instruction with B=256.
|
||||
STRTDATWR: LD B,0 ; 256 bytes to load.
|
||||
JP (IX)
|
||||
|
||||
WRITEDATA: OUTI
|
||||
JP NZ, 0F3FEH ; This is crucial, as the Z80 is running at 2MHz it is not fast enough so needs
|
||||
; hardware acceleration in the form of a banked ROM, if disk not ready jumps to IX, if
|
||||
; data ready, jumps to IY.
|
||||
DEC D
|
||||
JP NZ,0F3FEH ; If we havent read all sectors to form a 512 byte block, go for next sector.
|
||||
JR DATASTOP
|
||||
|
||||
; Read disk starting at the first logical sector in param block 1009/100A
|
||||
; Continue reading for the given size 100B/100C and store in the location
|
||||
; Pointed to by the address stored in the parameter block. 100D/100E
|
||||
?DSKREAD: LD A,MAXRDRETRY
|
||||
LD (RETRIES),A
|
||||
LD A,(SECTORCNT)
|
||||
LD B,A
|
||||
LD A,(HSTSEC)
|
||||
DSKREAD0A: DJNZ DSKREAD0B
|
||||
JR DSKREAD1
|
||||
DSKREAD0B: OR A
|
||||
RL A
|
||||
JR DSKREAD0A
|
||||
DSKREAD1: INC A
|
||||
LD (SECTORNO), A ; Convert from Host 512 byte sector into local sector according to paraameter block.
|
||||
LD HL,(HSTTRK)
|
||||
LD (TRACKNO),HL
|
||||
DSKREAD2: CALL SETTRKSEC ; Set current track & sector, get load address to HL
|
||||
DSKREAD3: CALL SETHEAD ; Set side reg
|
||||
CALL SEEK ; Command 1b output (seek)
|
||||
JP NZ,SEEKRETRY ;
|
||||
CALL OUTTKSEC ; Set track & sector reg
|
||||
LD IX, 0F3FEH ; As below. L03FE
|
||||
LD IY,READDATA ; Read sector into memory.
|
||||
DI
|
||||
;
|
||||
LD A,094H ; Read Sector multiple with Side Compare for side 1.
|
||||
CALL DISKCMDWAIT
|
||||
LD D,2 ; Regardless of 4x128, 2x256 or 1x512, we always read 512bytes by the 2x INI instruction with B=256.
|
||||
STRTDATRD: LD B,0 ; 256 bytes to load.
|
||||
JP (IX)
|
||||
|
||||
; Get data from disk sector to staging area.
|
||||
READDATA: INI
|
||||
JP NZ,0F3FEH ; This is crucial, as the Z80 is running at 2MHz it is not fast enough so needs
|
||||
; hardware acceleration in the form of a banked ROM, if disk not ready jumps to IX, if
|
||||
; data ready, jumps to IY.
|
||||
DEC D
|
||||
JP NZ,0F3FEH ; If we havent read all sectors to form a 512 byte block, go for next sector.
|
||||
;
|
||||
;
|
||||
DATASTOP: LD A,0D8H ; Force interrupt command, Immediate interrupt (I3 bit 3=1) of multiple sector read.
|
||||
CPL
|
||||
OUT (FDC_CR),A
|
||||
CALL WAITRDY ; Wait for controller to become ready, acknowledging interrupt.
|
||||
IN A,(FDC_STR) ; Check for errors.
|
||||
CPL
|
||||
AND 0FFH
|
||||
JR NZ,SEEKRETRY
|
||||
UPDSECTOR: PUSH HL
|
||||
LD A,(SECTORCNT)
|
||||
LD HL,SECTORNO
|
||||
ADD A,(HL) ; Update sector to account for sectors read. NB. All reads will start at such a position
|
||||
LD (HL), A ; that a read will not span a track or head. Ensure that disk formats meet an even 512byte format.
|
||||
POP HL
|
||||
MOTOROFF: LD A,MTROFFMSECS ; Schedule motor to be turned off.
|
||||
LD (MTROFFTIMER),A
|
||||
XOR A ; Successful read, return 0
|
||||
EI
|
||||
RET
|
||||
|
||||
SEEKRETRY: LD B,A ; Preserve the FDC Error byte.
|
||||
LD A,(RETRIES)
|
||||
DEC A
|
||||
LD (RETRIES),A
|
||||
LD A,B
|
||||
JP Z,RETRIESERR
|
||||
CALL DSKSEEKTK0
|
||||
LD A, (READOP)
|
||||
OR A
|
||||
LD A,(TRACKNO) ; NB. Track number is 16bit, FDC only uses lower 8bit and assumes little endian read.
|
||||
JP Z, DSKWRITE2 ; Try write again.
|
||||
JP DSKREAD2 ; Try the read again.
|
||||
|
||||
DISKCMDWAIT:LD (FDCCMD),A
|
||||
CPL
|
||||
OUT (FDC_CR),A
|
||||
CALL WAITBUSY
|
||||
RET
|
||||
|
||||
; Send a command to the disk controller.
|
||||
DSKCMD: LD (FDCCMD),A ; Store latest FDC command.
|
||||
CPL ; Compliment it (FDC bit value is reversed).
|
||||
OUT (FDC_CR),A ; Send command to FDC.
|
||||
CALL WAITRDY ; Wait to become ready.
|
||||
IN A,(FDC_STR) ; Get status register.
|
||||
CPL ; Inverse (FDC is reverse bit logic).
|
||||
RET
|
||||
|
||||
; Seek to programmed track.
|
||||
SEEK: LD A,01BH ; Seek command, load head, verify stepping 6ms.
|
||||
CALL DSKCMD
|
||||
AND 099H
|
||||
RET
|
||||
|
||||
; Set current track & sector, get load address to HL
|
||||
SETTRKSEC: CALL ?SELDRIVE
|
||||
LD A,(TRACKNO) ; NB. Track number is 16bit, FDC only uses lower 8bit and assumes little endian read.
|
||||
LD HL, HSTBUF
|
||||
RET
|
||||
|
||||
; Compute side/head.
|
||||
SETHEAD: CPL ;
|
||||
OUT (FDC_DR),A ; Output track no for SEEK command.
|
||||
PUSH HL
|
||||
LD HL,SECPERHEAD
|
||||
LD A,(SECTORNO) ; Check sector, if greater than sector per track, change head.
|
||||
CP (HL)
|
||||
POP HL
|
||||
JR NC,SETHD2 ; Yes, even, set side/head 1
|
||||
LD A,001H ; No, odd, set side/head 0
|
||||
JR SETHD3
|
||||
|
||||
; Set side/head register.
|
||||
SETHD2: XOR A ; Side 0
|
||||
SETHD3: CPL ; Side 1
|
||||
OUT (FDC_SIDE),A ; Side/head register.
|
||||
RET
|
||||
|
||||
; Set track and sector register.
|
||||
OUTTKSEC: PUSH HL
|
||||
LD HL,SECPERHEAD
|
||||
;
|
||||
LD C,FDC_DR ; Port for data retrieval in the INI instruction in main block.
|
||||
LD A,(TRACKNO) ; Current track number, NB. Track number is 16bit, FDC only uses lower 8bit and assumes little endian read.
|
||||
CPL
|
||||
OUT (FDC_TR),A ; Track reg
|
||||
;
|
||||
LD A,(SECTORNO) ; Current sector number
|
||||
CP (HL)
|
||||
JR C,OUTTKSEC2
|
||||
SUB (HL)
|
||||
INC A ; Account for the +1 added to ease comparisons.
|
||||
OUTTKSEC2: CPL
|
||||
OUT (FDC_SCR),A ; Sector reg
|
||||
POP HL
|
||||
RET
|
||||
|
||||
; Seek to track 0.
|
||||
DSKSEEKTK0: CALL DSKMTRON ; Make sure disk is spinning.
|
||||
LD A,00BH ; Restore command, seek track 0.
|
||||
CALL DSKCMD ; Send command to FDC.
|
||||
AND 085H ; Process result.
|
||||
XOR 004H
|
||||
RET Z
|
||||
JP DSKSEEKERR
|
||||
|
||||
; Wait for the drive to become ready.
|
||||
WAITRDY: PUSH DE
|
||||
PUSH HL
|
||||
CALL FDCDLY1
|
||||
LD E,007H
|
||||
WAITRDY2: LD HL,00000H
|
||||
WAITRDY3: DEC HL
|
||||
LD A,H
|
||||
OR L
|
||||
JR Z,WAITRDY4
|
||||
IN A,(FDC_STR)
|
||||
CPL
|
||||
RRCA
|
||||
JR C,WAITRDY3
|
||||
POP HL
|
||||
POP DE
|
||||
RET
|
||||
|
||||
WAITRDY4: DEC E
|
||||
JR NZ,WAITRDY2
|
||||
POP HL
|
||||
POP DE
|
||||
JP WAITRDYERR
|
||||
|
||||
WAITBUSY: PUSH DE
|
||||
PUSH HL
|
||||
CALL FDCDLY1
|
||||
LD E,007H ; 7 Chances of a 16bit down count delay waiting for DRQ.
|
||||
WAITBUSY2: LD HL,00000H
|
||||
WAITBUSY3: DEC HL
|
||||
LD A,H
|
||||
OR L
|
||||
JR Z,WAITBUSY4 ; Down counter expired, decrement retries, error on 0.
|
||||
IN A,(FDC_STR) ; Get the FDC Status
|
||||
CPL ; Switch to positive logic.
|
||||
RRCA ; Shift Busy flag into Carry.
|
||||
JR NC,WAITBUSY3 ; Busy not set, decrement counter and retry.
|
||||
POP HL
|
||||
POP DE
|
||||
RET
|
||||
|
||||
WAITBUSY4: DEC E
|
||||
JR NZ,WAITBUSY2
|
||||
POP HL
|
||||
POP DE
|
||||
JP DSKERR
|
||||
|
||||
|
||||
; Error processing. Consists of printing a message followed by debug data (if enabled) and returning with carry set
|
||||
; to indicate error.
|
||||
DSKERR: LD DE,LOADERR ; Loading error message
|
||||
JR HDLERROR
|
||||
|
||||
SELDRVERR: LD DE,SELDRVMSG ; Select drive error message.
|
||||
JR HDLERROR
|
||||
|
||||
WAITRDYERR: LD DE,WAITRDYMSG ; Waiting for ready timeout error message.
|
||||
JR HDLERROR
|
||||
|
||||
DSKSEEKERR: LD DE,DSKSEEKMSG ; Disk seek to track error message.
|
||||
JR HDLERROR
|
||||
|
||||
RETRIESERR: BIT 2,A ; Data overrun error if 1.
|
||||
LD DE,DATAOVRMSG
|
||||
JR NZ, RETRIESERR2
|
||||
BIT 3,A ; CRC error if 1.
|
||||
LD DE,CRCERRMSG
|
||||
JR NZ,RETRIESERR2
|
||||
LD DE,RETRIESMSG ; Data sector read error message.
|
||||
RETRIESERR2:
|
||||
|
||||
; Process error, dump debug data and return fail code.
|
||||
HDLERROR: LD HL,MSGSTRBUF ; Copy the error messae
|
||||
HOLERR1: LD A,(DE)
|
||||
LD (HL),A
|
||||
CP NUL
|
||||
JR Z,HOLERR2
|
||||
INC DE
|
||||
INC HL
|
||||
JR HOLERR1
|
||||
HOLERR2: LD DE,MSGSTRBUF
|
||||
HOLPRTSTR: LD A,(DE)
|
||||
OR A
|
||||
JR Z,HOLERR3
|
||||
INC DE
|
||||
HOLPRTSTR2: LD HL,QPRNT
|
||||
PUSH AF
|
||||
LD A,ROMBANK9 << 4 | ROMBANK11 ; Call CBIOS Bank 2 from CBIOS Bank 4
|
||||
CALL BANKTOBANK
|
||||
JR HOLPRTSTR
|
||||
HOLERR3: XOR A
|
||||
CALL ?DSKINIT
|
||||
CALL DSKMTRON
|
||||
LD A,001H ; Indicate error by setting 1 in A register.
|
||||
EI
|
||||
RET
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF FDC CONTROLLER FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
;--------------------------------------
|
||||
;
|
||||
; Message table
|
||||
;
|
||||
;--------------------------------------
|
||||
LOADERR: DB "DISK ERROR - LOADING", CR, NUL
|
||||
SELDRVMSG: DB "DISK ERROR - SELECT", CR, NUL
|
||||
WAITRDYMSG: DB "DISK ERROR - WAIT", CR, NUL
|
||||
DSKSEEKMSG: DB "DISK ERROR - SEEK", CR, NUL
|
||||
RETRIESMSG: DB "DISK ERROR - RETRIES", CR, NUL
|
||||
DATAOVRMSG: DB "DISK ERROR - DATA OVERRUN", CR, NUL
|
||||
CRCERRMSG: DB "DISK ERROR - CRC ERROR", CR, NUL
|
||||
|
||||
ALIGN_NOPS UROMADDR + 0800h
|
||||
|
||||
; Bring in additional macros.
|
||||
|
||||
@@ -55,24 +55,15 @@
|
||||
; -ALV Address of a scratch pad area used by the BDOS to keep disk storage allocation information.
|
||||
; This address is different for each DPH.
|
||||
;------------------------------------------------------------------------------------------------------------
|
||||
DPBASE: DW 0000H, 0000H, 0000H, 0000H, CDIRBUF, DPBLOCK1, CSV0, ALV0
|
||||
DW 0000H, 0000H, 0000H, 0000H, CDIRBUF, DPBLOCK2, CSV1, ALV1
|
||||
DW 0000H, 0000H, 0000H, 0000H, CDIRBUF, DPBLOCK3, CSV2, ALV2
|
||||
DW 0000H, 0000H, 0000H, 0000H, CDIRBUF, DPBLOCK3, CSV3, ALV3
|
||||
ALIGN_NOPS DPBASE ; Space for 2xROM, 2xFD, 3xSD or upto 7 drives
|
||||
; These entries are created dynamically based on hardware available.
|
||||
|
||||
; NB. The Disk Parameter Blocks are stored in CBIOS ROM to save RAM space.
|
||||
|
||||
;------------------------------------------------------------------------------------------------------------
|
||||
; CPN Disk work areas.
|
||||
;------------------------------------------------------------------------------------------------------------
|
||||
CDIRBUF: DS 128 ; scratch directory area
|
||||
CSV0: DS 32 ; (DRM + 1)/4 = scratch area for drive 0.
|
||||
ALV0: DS (720/8)+1 ; (DSM/8) + 1 = allocation vector 0 NB.Set to largest DSM declared in DPB tables as drives can be switched.
|
||||
CSV1: DS 32 ; scratch area for drive 1.
|
||||
ALV1: DS (720/8)+1 ; allocation vector 1
|
||||
CSV2: DS 32 ; scratch area for drive 2.
|
||||
ALV2: DS (720/8)+1 ; allocation vector 2
|
||||
CSV3: DS 32 ; scratch area for drive 3.
|
||||
ALV3: DS (720/8)+1 ; allocation vector 3
|
||||
|
||||
ALIGN CBIOSDATA
|
||||
ALIGN_NOPS CDIRBUF ; Memory work areas, just allocate the space.
|
||||
ALIGN_NOPS CSVALVMEM
|
||||
ALIGN_NOPS CSVALVEND
|
||||
ALIGN CBIOSDATA
|
||||
|
||||
@@ -56,9 +56,13 @@ WRITE EQU CBIOSSTART + 42
|
||||
FRSTAT EQU CBIOSSTART + 45
|
||||
SECTRN EQU CBIOSSTART + 48
|
||||
UNUSED EQU CBIOSSTART + 51
|
||||
BANKTOBANK EQU CBIOSSTART + 54
|
||||
CCP EQU CBASE
|
||||
CCPCLRBUF EQU CBASE + 3
|
||||
CPMDPBASE EQU CPMBIOS
|
||||
DPBASE EQU CPMBIOS
|
||||
CDIRBUF EQU CPMBIOS + (MAXDISKS * 16)
|
||||
CSVALVMEM EQU CDIRBUF + 128
|
||||
CSVALVEND EQU CSVALVMEM + 1253
|
||||
IOBYT EQU 00003H ; IOBYTE address
|
||||
CDISK EQU 00004H ; Address of Current drive name and user number
|
||||
CPMUSERDMA EQU 00080h ; Default CPM User DMA address.
|
||||
@@ -72,12 +76,6 @@ DPBLOCK5 EQU DPBLOCK4 + DPSIZE
|
||||
DPBLOCK6 EQU DPBLOCK5 + DPSIZE
|
||||
DPBLOCK7 EQU DPBLOCK6 + DPSIZE
|
||||
|
||||
; BIOS equates
|
||||
NDISKS EQU 4 ; Number of Disk Drives
|
||||
KEYBUFSIZE EQU 16 ; Ensure this is a power of 2, max size 256.
|
||||
|
||||
; Debugging
|
||||
ENADEBUG EQU 1 ; Enable debugging logic, 1 = enable, 0 = disable
|
||||
|
||||
;-----------------------------------------------
|
||||
; Configurable settings.
|
||||
@@ -101,24 +99,53 @@ SCRNSZ: EQU COLW * ROW ; Total
|
||||
SCRLW: EQU COLW / 8 ; Number of 8 byte regions in a line for hardware scroll.
|
||||
MODE80C: EQU 1
|
||||
|
||||
; BIOS equates
|
||||
MAXDISKS EQU 7 ; Max number of Drives supported
|
||||
KEYBUFSIZE EQU 16 ; Ensure this is a power of 2, max size 256.
|
||||
|
||||
; Debugging
|
||||
ENADEBUG EQU 1 ; Enable debugging logic, 1 = enable, 0 = disable
|
||||
|
||||
;-------------------------------------------------------
|
||||
; Function entry points in the CBIOS ROMS
|
||||
;-------------------------------------------------------
|
||||
|
||||
; Public functions in CBIOS User ROM Bank 1.
|
||||
; Public functions in CBIOS User ROM Bank 1 - utility functions, ie. Audio.
|
||||
QREBOOT EQU 9 + UROMADDR
|
||||
QMELDY EQU 12 + UROMADDR
|
||||
QTEMP EQU 15 + UROMADDR
|
||||
QMSTA EQU 18 + UROMADDR
|
||||
QMSTP EQU 21 + UROMADDR
|
||||
QBEL EQU 24 + UROMADDR
|
||||
QMODE EQU 27 + UROMADDR
|
||||
QTIMESET EQU 30 + UROMADDR
|
||||
QTIMEREAD EQU 33 + UROMADDR
|
||||
QCHKKY EQU 36 + UROMADDR
|
||||
QGETKY EQU 39 + UROMADDR
|
||||
|
||||
; Public functions in CBIOS User ROM Bank 1.
|
||||
; Public functions in CBIOS User ROM Bank 2 - Screen / ANSI terminal functions.
|
||||
QPRNT EQU 9 + UROMADDR
|
||||
QPRTHX EQU 12 + UROMADDR
|
||||
QPRTHL EQU 15 + UROMADDR
|
||||
QANSITERM EQU 18 + UROMADDR
|
||||
|
||||
; Public functions in CBIOS User ROM Bank 3 - SD Card functions.
|
||||
SD_INIT EQU 9 + UROMADDR
|
||||
SD_READ EQU 12 + UROMADDR
|
||||
SD_WRITE EQU 15 + UROMADDR
|
||||
SD_GETLBA EQU 18 + UROMADDR
|
||||
SDC_READ EQU 21 + UROMADDR
|
||||
SDC_WRITE EQU 24 + UROMADDR
|
||||
|
||||
; Public functions in CBIOS User ROM Bank 4 - Floppy Disk Controller functions.
|
||||
QDSKINIT EQU 9 + UROMADDR
|
||||
QSETDRVCFG EQU 12 + UROMADDR
|
||||
QSETDRVMAP EQU 15 + UROMADDR
|
||||
QSELDRIVE EQU 18 + UROMADDR
|
||||
QGETMAPDSK EQU 21 + UROMADDR
|
||||
QDSKREAD EQU 24 + UROMADDR
|
||||
QDSKWRITE EQU 27 + UROMADDR
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
; Memory mapped ports in hardware.
|
||||
@@ -157,10 +184,12 @@ SPI_IN EQU 0FEH
|
||||
;
|
||||
DOUT_LOW EQU 000H
|
||||
DOUT_HIGH EQU 004H
|
||||
DOUT_MASK EQU 004H
|
||||
DIN_LOW EQU 000H
|
||||
DIN_HIGH EQU 001H
|
||||
CLOCK_LOW EQU 000H
|
||||
CLOCK_HIGH EQU 002H
|
||||
CLOCK_MASK EQU 0FDH
|
||||
CS_LOW EQU 000H
|
||||
CS_HIGH EQU 001H
|
||||
|
||||
@@ -198,19 +227,21 @@ WRKROMBK2: EQU 01019H ; WORKI
|
||||
; the User ROM bank.
|
||||
;-----------------------------------------------
|
||||
MROMPAGES EQU 8
|
||||
USRROMPAGES EQU 12
|
||||
ROMBANK0 EQU 0
|
||||
ROMBANK1 EQU 1
|
||||
ROMBANK2 EQU 2
|
||||
ROMBANK3 EQU 3
|
||||
ROMBANK4 EQU 4
|
||||
ROMBANK5 EQU 5
|
||||
ROMBANK6 EQU 6
|
||||
ROMBANK7 EQU 7
|
||||
ROMBANK8 EQU 8
|
||||
ROMBANK9 EQU 9
|
||||
ROMBANK10 EQU 10
|
||||
ROMBANK11 EQU 11
|
||||
USRROMPAGES EQU 12 ; Monitor ROM : User ROM
|
||||
ROMBANK0 EQU 0 ; MROM SA1510 40 Char : RFS Bank 0 - Main RFS Entry point and functions.
|
||||
ROMBANK1 EQU 1 ; MROM SA1510 80 Char : RFS Bank 1 - Floppy disk controller and utilities.
|
||||
ROMBANK2 EQU 2 ; CPM 2.2 CBIOS : RFS Bank 2 - SD Card controller and utilities.
|
||||
ROMBANK3 EQU 3 ; RFS Utilities : RFS Bank 3 - Cmdline tools (Memory, Printer, Help)
|
||||
ROMBANK4 EQU 4 ; Free : RFS Bank 4 - CMT Utilities.
|
||||
ROMBANK5 EQU 5 ; Free : RFS Bank 5
|
||||
ROMBANK6 EQU 6 ; Free : RFS Bank 6
|
||||
ROMBANK7 EQU 7 ; Free : RFS Bank 7 - Memory and timer test utilities.
|
||||
ROMBANK8 EQU 8 ; : CBIOS Bank 1 - Utilities
|
||||
ROMBANK9 EQU 9 ; : CBIOS Bank 2 - Screen / ANSI Terminal
|
||||
ROMBANK10 EQU 10 ; : CBIOS Bank 3 - SD Card
|
||||
ROMBANK11 EQU 11 ; : CBIOS Bank 4 - Floppy disk controller.
|
||||
|
||||
|
||||
|
||||
OBJCD EQU 001h
|
||||
|
||||
@@ -288,6 +319,67 @@ CLRKEY EQU 0F7H
|
||||
HOMEKEY EQU 0F8H
|
||||
BREAKKEY EQU 0FBH
|
||||
|
||||
|
||||
; MMC/SD command (SPI mode)
|
||||
CMD0 EQU 64 + 0 ; GO_IDLE_STATE
|
||||
CMD1 EQU 64 + 1 ; SEND_OP_COND
|
||||
ACMD41 EQU 0x40+41 ; SEND_OP_COND (SDC)
|
||||
CMD8 EQU 64 + 8 ; SEND_IF_COND
|
||||
CMD9 EQU 64 + 9 ; SEND_CSD
|
||||
CMD10 EQU 64 + 10 ; SEND_CID
|
||||
CMD12 EQU 64 + 12 ; STOP_TRANSMISSION
|
||||
CMD13 EQU 64 + 13 ; SEND_STATUS
|
||||
ACMD13 EQU 0x40+13 ; SD_STATUS (SDC)
|
||||
CMD16 EQU 64 + 16 ; SET_BLOCKLEN
|
||||
CMD17 EQU 64 + 17 ; READ_SINGLE_BLOCK
|
||||
CMD18 EQU 64 + 18 ; READ_MULTIPLE_BLOCK
|
||||
CMD23 EQU 64 + 23 ; SET_BLOCK_COUNT
|
||||
ACMD23 EQU 0x40+23 ; SET_WR_BLK_ERASE_COUNT (SDC)
|
||||
CMD24 EQU 64 + 24 ; WRITE_BLOCK
|
||||
CMD25 EQU 64 + 25 ; WRITE_MULTIPLE_BLOCK
|
||||
CMD32 EQU 64 + 32 ; ERASE_ER_BLK_START
|
||||
CMD33 EQU 64 + 33 ; ERASE_ER_BLK_END
|
||||
CMD38 EQU 64 + 38 ; ERASE
|
||||
CMD55 EQU 64 + 55 ; APP_CMD
|
||||
CMD58 EQU 64 + 58 ; READ_OCR
|
||||
|
||||
; Card type flags (CardType)
|
||||
CT_MMC EQU 001H ; MMC ver 3
|
||||
CT_SD1 EQU 002H ; SD ver 1
|
||||
CT_SD2 EQU 004H ; SD ver 2
|
||||
CT_SDC EQU CT_SD1|CT_SD2 ; SD
|
||||
CT_BLOCK EQU 008H ; Block addressing
|
||||
|
||||
; Disk types.
|
||||
DSKTYP_FDC EQU 0 ; Type of disk is a Floppy disk and handled by the FDC controller.
|
||||
DSKTYP_ROM EQU 1 ; Type of disk is a ROM and handled by the ROM methods.
|
||||
DSKTYP_SDC EQU 2 ; Type of disk is an SD Card and handled by the SD Card methods.
|
||||
|
||||
;
|
||||
; Rom Filing System constants.
|
||||
;
|
||||
RFS_DIRENT EQU 256 ; Directory entries in the RFS directory.
|
||||
RFS_DIRENTSZ EQU 32 ; Size of a directory entry.
|
||||
RFS_DIRSIZE EQU RFS_DIRENT * RFS_DIRENTSZ ; Total size of the directory.
|
||||
RFS_BLOCKSZ EQU 65536 ; Size of a file block per directory entry.
|
||||
RFS_IMGSZ EQU RFS_DIRSIZE + (RFS_DIRENT * RFS_BLOCKSZ) ; Total size of the RFS image.
|
||||
|
||||
;
|
||||
; CPM constants
|
||||
;
|
||||
CPM_SD_SEC EQU 32
|
||||
CPM_SD_TRK EQU 1024
|
||||
CPM_SD_IMGSZ EQU CPM_SD_TRK * CPM_SD_SEC * SD_SECSIZE
|
||||
|
||||
;
|
||||
; SD Card constants.
|
||||
;
|
||||
SD_SECSIZE EQU 512 ; Default size of an SD Sector
|
||||
SD_SECPTRK EQU CPM_SD_SEC ; Sectors of SD_SECSIZE per virtual track.
|
||||
SD_TRACKS EQU CPM_SD_TRK ; Number of virtual tracks per disk image.
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
; BIOS WORK AREA (MZ80A)
|
||||
;-----------------------------------------------
|
||||
@@ -301,6 +393,8 @@ KEYWRITE: DS virtual 2 ; Point
|
||||
KEYREAD: DS virtual 2 ; Pointer into the buffer where the next character can be read.
|
||||
KEYLAST: DS virtual 1 ; KEY LAST VALUE
|
||||
KEYRPT: DS virtual 1 ; KEY REPEAT COUNTER
|
||||
USRBANKSAV: DS virtual 1 ; Save user bank number when calling another user bank.
|
||||
HLSAVE: DS virtual 2 ; Space to save HL register when manipulating stack.
|
||||
;
|
||||
SPV:
|
||||
IBUFE: ; TAPE BUFFER (128 BYTES)
|
||||
@@ -339,6 +433,7 @@ OCTV: DS virtual 1 ; OCTAV
|
||||
RATIO: DS virtual 2 ; ONPU RATIO
|
||||
;BUFER: DS virtual 81 ; GET LINE BUFFER
|
||||
;KEYBUF: DS virtual 1 ; KEY BUFFER
|
||||
DRVAVAIL DS virtual 1 ; Flag to indicate which drive controllers are available. Bit 2 = SD, Bit 1 = ROM, Bit 0 = FDC
|
||||
TIMESEC DS virtual 6 ; RTC 48bit TIME IN MILLISECONDS
|
||||
FDCCMD DS virtual 1 ; LAST FDC COMMAND SENT TO CONTROLLER.
|
||||
MOTON DS virtual 1 ; MOTOR ON = 1, OFF = 0
|
||||
@@ -355,13 +450,13 @@ TMPCNT DS virtual 2 ; TEMPO
|
||||
CPMROMLOC: DS virtual 2 ; Upper Byte = ROM Bank, Lower Byte = Page of CPM Image.
|
||||
CPMROMDRV0: DS virtual 2 ; Upper Byte = ROM Bank, Lower Byte = Page of CPM Rom Drive Image Disk 0.
|
||||
CPMROMDRV1: DS virtual 2 ; Upper Byte = ROM Bank, Lower Byte = Page of CPM Rom Drive Image Disk 1.
|
||||
DISKMAP: DS virtual NDISKS ; Disk map of CPM logical to physical controller disk.
|
||||
NDISKS: DS virtual 1 ; Dynamically calculated number of disks on boot.
|
||||
DISKMAP: DS virtual MAXDISKS ; Disk map of CPM logical to physical controller disk.
|
||||
FDCDISK: DS virtual 1 ; Physical disk number.
|
||||
SECPERTRK: DS virtual 1 ; Sectors per track for 1 head.
|
||||
SECPERHEAD: DS virtual 1 ; Sectors per head.
|
||||
SECTORCNT: DS virtual 1 ; Sector size as a count of how many sectors make 512 bytes.
|
||||
DISKTYPE: DS virtual 1 ; Disk type of current selection.
|
||||
ROMDRV: DS virtual 1 ; ROM Drive Image to use.
|
||||
MTROFFTIMER:DS virtual 1 ; Second down counter for FDC motor off.
|
||||
;
|
||||
SEKDSK: DS virtual 1 ; Seek disk number
|
||||
@@ -390,6 +485,11 @@ DMAADDR: DS virtual 2 ; Last
|
||||
HSTBUF: DS virtual 512 ; Host buffer for disk sector storage
|
||||
HSTBUFE:
|
||||
|
||||
SDVER: DS virtual 1 ; SD Card version.
|
||||
SDCAP: DS virtual 1 ; SD Card capabilities..
|
||||
SDSTARTSEC DS virtual 4 ; Starting sector of data to read/write from/to SD card.
|
||||
SDBUF: DS virtual 11 ; SD Card command fram buffer for the command and response storage.
|
||||
|
||||
CURSORPSAV DS virtual 2 ; Cursor save position;default 0,0
|
||||
HAVELOADED DS virtual 1 ; To show that a value has been put in for Ansi emualtor.
|
||||
ANSIFIRST DS virtual 1 ; Holds first character of Ansi sequence
|
||||
@@ -414,9 +514,8 @@ COLOUR EQU 0
|
||||
SPSAVE: DS virtual 2 ; CPM Stack save.
|
||||
SPISRSAVE: DS virtual 2
|
||||
VAREND EQU $ ; End of variables
|
||||
|
||||
; Stack space for the CBIOS.
|
||||
DS virtual 64
|
||||
MSGSTRBUF: DS virtual 128 ; Lower end of the stack space is for interbank message printing, ie.space for a string to print.
|
||||
BIOSSTACK EQU $
|
||||
; Stack space for the Interrupt Service Routine.
|
||||
DS virtual 16 ; Max 8 stack pushes.
|
||||
|
||||
@@ -26,6 +26,13 @@
|
||||
;- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
;-----------------------------------------------
|
||||
; Entry/compilation start points.
|
||||
;-----------------------------------------------
|
||||
UROMADDR EQU 0E800H ; Start of User ROM Address space.
|
||||
RFSJMPTABLE EQU UROMADDR + 00080H ; Start of jump table.
|
||||
FDCROMADDR EQU 0F000H
|
||||
|
||||
;-------------------------------------------------------
|
||||
; Function entry points in the standard SA-1510 Monitor.
|
||||
;-------------------------------------------------------
|
||||
@@ -99,6 +106,23 @@ RFSBK2: EQU 0EFFDh ; Selec
|
||||
RFSRST1: EQU 0EFFEh ; Reset RFS Bank1 to original.
|
||||
RFSRST2: EQU 0EFFFh ; Reset RFS Bank2 to original.
|
||||
|
||||
;-----------------------------------------------
|
||||
; IO ports in hardware and values.
|
||||
;-----------------------------------------------
|
||||
SPI_OUT EQU 0FFH
|
||||
SPI_IN EQU 0FEH
|
||||
;
|
||||
DOUT_LOW EQU 000H
|
||||
DOUT_HIGH EQU 004H
|
||||
DOUT_MASK EQU 004H
|
||||
DIN_LOW EQU 000H
|
||||
DIN_HIGH EQU 001H
|
||||
CLOCK_LOW EQU 000H
|
||||
CLOCK_HIGH EQU 002H
|
||||
CLOCK_MASK EQU 0FDH
|
||||
CS_LOW EQU 000H
|
||||
CS_HIGH EQU 001H
|
||||
|
||||
;-----------------------------------------------
|
||||
; Rom File System Header (MZF)
|
||||
;-----------------------------------------------
|
||||
@@ -122,6 +146,7 @@ MZFHDRSZ EQU 128
|
||||
RFSSECTSZ EQU 256
|
||||
MROMSIZE EQU 4096
|
||||
UROMSIZE EQU 2048
|
||||
FNSIZE EQU 17
|
||||
|
||||
;-----------------------------------------------
|
||||
; ROM Banks, 0-7 are reserved for alternative
|
||||
@@ -133,55 +158,84 @@ UROMSIZE EQU 2048
|
||||
; the User ROM bank.
|
||||
;-----------------------------------------------
|
||||
MROMPAGES EQU 8
|
||||
USRROMPAGES EQU 12
|
||||
ROMBANK0 EQU 0
|
||||
ROMBANK1 EQU 1
|
||||
ROMBANK2 EQU 2
|
||||
ROMBANK3 EQU 3
|
||||
ROMBANK4 EQU 4
|
||||
ROMBANK5 EQU 5
|
||||
ROMBANK6 EQU 6
|
||||
ROMBANK7 EQU 7
|
||||
ROMBANK8 EQU 8
|
||||
ROMBANK9 EQU 9
|
||||
ROMBANK10 EQU 10
|
||||
ROMBANK11 EQU 11
|
||||
USRROMPAGES EQU 12 ; Monitor ROM : User ROM
|
||||
ROMBANK0 EQU 0 ; MROM SA1510 40 Char : RFS Bank 0 - Main RFS Entry point and functions.
|
||||
ROMBANK1 EQU 1 ; MROM SA1510 80 Char : RFS Bank 1 - Floppy disk controller and utilities.
|
||||
ROMBANK2 EQU 2 ; CPM 2.2 CBIOS : RFS Bank 2 - SD Card controller and utilities.
|
||||
ROMBANK3 EQU 3 ; RFS Utilities : RFS Bank 3 - Cmdline tools (Memory, Printer, Help)
|
||||
ROMBANK4 EQU 4 ; Free : RFS Bank 4 - CMT Utilities.
|
||||
ROMBANK5 EQU 5 ; Free : RFS Bank 5
|
||||
ROMBANK6 EQU 6 ; Free : RFS Bank 6
|
||||
ROMBANK7 EQU 7 ; Free : RFS Bank 7 - Memory and timer test utilities.
|
||||
ROMBANK8 EQU 8 ; : CBIOS Bank 1 - Utilities
|
||||
ROMBANK9 EQU 9 ; : CBIOS Bank 2 - Screen / ANSI Terminal
|
||||
ROMBANK10 EQU 10 ; : CBIOS Bank 3 - SD Card
|
||||
ROMBANK11 EQU 11 ; : CBIOS Bank 4 - Floppy disk controller.
|
||||
|
||||
OBJCD EQU 001h
|
||||
|
||||
;-----------------------------------------------
|
||||
; Common character definitions.
|
||||
;-----------------------------------------------
|
||||
SCROLL EQU 01H ; Set scrool direction UP.
|
||||
BELL EQU 07H
|
||||
SPACE EQU 20H
|
||||
TAB EQU 09H ; TAB ACROSS (8 SPACES FOR SD-BOARD)
|
||||
CR EQU 0DH
|
||||
LF EQU 0AH
|
||||
FF EQU 0CH
|
||||
ESC EQU 1BH
|
||||
DELETE EQU 7FH
|
||||
BACKS EQU 08H
|
||||
SCROLL EQU 001H ; Set scrool direction UP.
|
||||
BELL EQU 007H
|
||||
SPACE EQU 020H
|
||||
TAB EQU 009H ; TAB ACROSS (8 SPACES FOR SD-BOARD)
|
||||
CR EQU 00DH
|
||||
LF EQU 00AH
|
||||
FF EQU 00CH
|
||||
ESC EQU 01BH
|
||||
DELETE EQU 07FH
|
||||
BACKS EQU 008H
|
||||
SOH EQU 1 ; For XModem etc.
|
||||
EOT EQU 4
|
||||
ACK EQU 6
|
||||
NAK EQU 15H
|
||||
NUL EQU 00H
|
||||
NULL EQU 000H
|
||||
CTRL_A EQU 001H
|
||||
CTRL_B EQU 002H
|
||||
CTRL_C EQU 003H
|
||||
CTRL_D EQU 004H
|
||||
CTRL_E EQU 005H
|
||||
CTRL_F EQU 006H
|
||||
CTRL_G EQU 007H
|
||||
CTRL_H EQU 008H
|
||||
CTRL_I EQU 009H
|
||||
CTRL_J EQU 00AH
|
||||
CTRL_K EQU 00BH
|
||||
CTRL_L EQU 00CH
|
||||
CTRL_M EQU 00DH
|
||||
CTRL_N EQU 00EH
|
||||
CTRL_O EQU 00FH
|
||||
CTRL_P EQU 010H
|
||||
CTRL_Q EQU 011H
|
||||
CTRL_R EQU 012H
|
||||
CTRL_S EQU 013H
|
||||
CTRL_T EQU 014H
|
||||
CTRL_U EQU 015H
|
||||
CTRL_V EQU 016H
|
||||
CTRL_W EQU 017H
|
||||
CTRL_X EQU 018H
|
||||
CTRL_Y EQU 019H
|
||||
CTRL_Z EQU 01AH
|
||||
CTRL_SLASH EQU 01CH
|
||||
CTRL_RB EQU 01DH
|
||||
CTRL_CAPPA EQU 01EH
|
||||
CTRL_UNDSCR EQU 01FH
|
||||
CTRL_AT EQU 000H
|
||||
NOKEY EQU 0F0H
|
||||
CURSRIGHT EQU 0F1H
|
||||
CURSLEFT EQU 0F2H
|
||||
CURSUP EQU 0F3H
|
||||
CURSDOWN EQU 0F4H
|
||||
DBLZERO EQU 0F5H
|
||||
INSERT EQU 0F6H
|
||||
CLRKEY EQU 0F7H
|
||||
HOMEKEY EQU 0F8H
|
||||
BREAKKEY EQU 0FBH
|
||||
|
||||
|
||||
SPI_OUT EQU 0FFH
|
||||
SPI_IN EQU 0FEH
|
||||
DOUT_LOW EQU 000H
|
||||
DOUT_HIGH EQU 004H
|
||||
DOUT_MASK EQU 004H
|
||||
DIN_LOW EQU 000H
|
||||
DIN_HIGH EQU 001H
|
||||
CLOCK_LOW EQU 000H
|
||||
CLOCK_HIGH EQU 002H
|
||||
CLOCK_MASK EQU 0FDH
|
||||
CS_LOW EQU 000H
|
||||
CS_HIGH EQU 001H
|
||||
|
||||
; MMC/SD command (SPI mode)
|
||||
CMD0 EQU 64 + 0 ; GO_IDLE_STATE
|
||||
CMD1 EQU 64 + 1 ; SEND_OP_COND
|
||||
@@ -234,7 +288,7 @@ SDDIR_SSEC EQU 013H
|
||||
SDDIR_SIZE EQU 015H
|
||||
SDDIR_LOAD EQU 017H
|
||||
SDDIR_EXEC EQU 019H
|
||||
SDDIR_FNSZ EQU 17
|
||||
SDDIR_FNSZ EQU FNSIZE
|
||||
SDDIR_ENTSZ EQU 32
|
||||
|
||||
;-----------------------------------------------
|
||||
@@ -247,7 +301,7 @@ STACK: EQU 010F0H
|
||||
SPV:
|
||||
IBUFE: ; TAPE BUFFER (128 BYTES)
|
||||
ATRB: DS virtual 1 ; ATTRIBUTE
|
||||
NAME: DS virtual 17 ; FILE NAME
|
||||
NAME: DS virtual FNSIZE ; FILE NAME
|
||||
SIZE: DS virtual 2 ; BYTESIZE
|
||||
DTADR: DS virtual 2 ; DATA ADDRESS
|
||||
EXADR: DS virtual 2 ; EXECUTION ADDRESS
|
||||
|
||||
1078
software/asm/rfs.asm
1078
software/asm/rfs.asm
File diff suppressed because it is too large
Load Diff
@@ -27,12 +27,12 @@
|
||||
;- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
;======================================
|
||||
;============================================================
|
||||
;
|
||||
; USER ROM BANK 1
|
||||
; USER ROM BANK 1 - Floppy Disk Controller functions.
|
||||
;
|
||||
;======================================
|
||||
ORG 0E800h
|
||||
;============================================================
|
||||
ORG UROMADDR
|
||||
|
||||
;--------------------------------
|
||||
; Common code spanning all banks.
|
||||
@@ -109,11 +109,19 @@ TRK0FD3 EQU 01004H
|
||||
TRK0FD4 EQU 01005H
|
||||
RETRIES EQU 01006H
|
||||
BPARA EQU 01008H
|
||||
;======================================
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF FLOPPY DISK CONTROLLER FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; Method to check if the floppy interface ROM is present and if it is, jump to its entry point.
|
||||
;
|
||||
; Floppy Disk Interface
|
||||
;
|
||||
;======================================
|
||||
FDCK: CALL FDCKROM ; Check to see if the Floppy ROM is present, exit if it isnt.
|
||||
CALL Z,0F000h
|
||||
RET ; JP CMDCMPEND
|
||||
FDCKROM: LD A,(0F000h)
|
||||
OR A
|
||||
RET
|
||||
|
||||
FLOPPY: PUSH DE ; Preserve pointer to input buffer.
|
||||
LD DE,BPARA ; Copy disk parameter block into RAM work area. (From)
|
||||
@@ -479,7 +487,15 @@ L0300: IN A,(0D8H) ; Sta
|
||||
JR C,L0300 ; Wait on data reg ready
|
||||
JP (IY) ; to f1df
|
||||
|
||||
; Messages
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF FLOPPY DISK CONTROLLER FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
;--------------------------------------
|
||||
;
|
||||
; Message table
|
||||
;
|
||||
;--------------------------------------
|
||||
BOOTDRV: DB "FLOPPY BOOT DRIVE ?", 00DH
|
||||
LOADERR: DB "DISK LOADING ERROR", 00DH
|
||||
IPLLOAD: DB "DISK LOADING ", 00DH
|
||||
@@ -492,13 +508,11 @@ DSKID: DB 002H, "IPLPRO"
|
||||
; Parameter block to indicate configuration and load area.
|
||||
PRMBLK: DB 000H, 000H, 000H, 000H, 001H, 000H, 0CEH, 000H, 000H, 000H, 000H
|
||||
|
||||
; Ensure we fill the entire 1K by padding with FF's.
|
||||
; Ensure we fill the entire 2K by padding with FF's.
|
||||
ALIGN 0EBFDh
|
||||
DB 0FFh
|
||||
|
||||
L03FE: JP (IY)
|
||||
;DB 0DDH
|
||||
;DB 0E9H
|
||||
|
||||
ALIGN 0EFFFh
|
||||
DB 0FFh
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
;- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
;======================================
|
||||
;===========================================================
|
||||
;
|
||||
; USER ROM BANK 2
|
||||
; USER ROM BANK 2 - SD Card Controller functions.
|
||||
;
|
||||
;======================================
|
||||
ORG 0E800h
|
||||
;===========================================================
|
||||
ORG UROMADDR
|
||||
|
||||
;--------------------------------
|
||||
; Common code spanning all banks.
|
||||
@@ -98,7 +98,9 @@ BKSWRET2: POP BC
|
||||
POP AF
|
||||
RET ; Return to caller.
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF SD CONTROLLER FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; Method to initialise the SD card.
|
||||
;
|
||||
@@ -308,17 +310,19 @@ SDACMD: PUSH AF
|
||||
LD HL,00000H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
|
||||
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
|
||||
CALL SDCMD
|
||||
LD A,(SDBUF+6) ; Should be a response of 0 whereby the card has left idle.
|
||||
DEC A
|
||||
JR NZ,SDACMD
|
||||
|
||||
POP HL
|
||||
POP DE
|
||||
LD A,(SDBUF+6) ; Should be a response of 0 or 1.
|
||||
CP 2
|
||||
JR NC,SDACMD0
|
||||
POP AF
|
||||
CALL SDCMD
|
||||
LD A,(SDBUF+6) ; Should be a response of 0 whereby the card has left idle.
|
||||
OR A
|
||||
RET
|
||||
SDACMD0: POP AF
|
||||
CP 1
|
||||
RET
|
||||
|
||||
; Method to send Application Command 41 to the SD card. This command involves retries and delays
|
||||
; hence coded seperately.
|
||||
@@ -331,8 +335,6 @@ SDACMD1: PUSH BC
|
||||
LD HL,00040H ; NB. Important, HL should be coded as LH due to little endian and the way it is used in SDCMD.
|
||||
LD DE,00000H ; NB. Important, DE should be coded as ED due to little endian and the way it is used in SDCMD.
|
||||
CALL SDACMD
|
||||
LD A,(SDBUF+6) ; Should be a response of 0 whereby the card has left idle.
|
||||
OR A
|
||||
JR Z,SDACMD3
|
||||
LD BC,12903 ; Delay for at least 200mS for the card to recover and be ready.
|
||||
SDACMD2: DEC BC ; 6T
|
||||
@@ -346,7 +348,10 @@ SDACMD2: DEC BC ; 6T
|
||||
OR C
|
||||
JR NZ,SDACMD1
|
||||
LD A,1
|
||||
SDACMD3: OR A
|
||||
OR A ; Retries exceeded, return error.
|
||||
RET
|
||||
SDACMD3: POP BC ; Success, tidy up stack and exit with Z set.
|
||||
XOR A
|
||||
RET
|
||||
|
||||
; Method to send a byte to the SD card via the SPI protocol.
|
||||
@@ -434,6 +439,7 @@ SPISKIP: PUSH BC
|
||||
; This is done as follows: <MSB> <2> <1> <0> => <2> <1> <0> 0 (ie. 8 bit shift): Shift left <0> with carry, shift left <1> shift left <2>, 0 to <LSB>
|
||||
;
|
||||
; Input: HL = Stack offset.
|
||||
;
|
||||
LBATOADDR: LD HL,(SDSTARTSEC+1)
|
||||
LD A,(HL) ; Start ny retrieving bytes as HED0
|
||||
INC HL
|
||||
@@ -459,314 +465,6 @@ LBATOADDR: LD HL,(SDSTARTSEC+1)
|
||||
LD (BC),A
|
||||
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: on Stack : Position 2 = unsigned int count of 2 bytes. - The count of bytes to read.
|
||||
; ; Position 4 = unsigned int offset of 2 bytes. - The offset in the 512 byte sector to commence read.
|
||||
; ; Position 6 = unsigned long sector of 4 bytes. - The sector number or direct byte address for older cards.
|
||||
; ; Position 10 = unsigned char BYTE *buf of 2 bytes- Pointer to a buffer where the bytes should be stored
|
||||
; ; Output: A = 0 - All ok. A > 0 - error occurred.
|
||||
; ;
|
||||
;SD_READP: 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,READP_3 ; If it has CT_BLOCK then use sector numbers otherwise multiply up to bytes.
|
||||
;
|
||||
; LD HL,6 + 2 ; It isnt so we need to convert the block to bytes by x512.
|
||||
; CALL LBATOADDR
|
||||
;
|
||||
;READP_3: LD A,1
|
||||
; LD (RESULT),A
|
||||
;
|
||||
; ; A = ACMD to send
|
||||
; ; LHED = Argument, ie. ACMD = A, L, H, E, D, CRC
|
||||
; LD HL,6 ; Sector is stored as 3rd paramneter at offset 6, retrieve and arrange in little endian order in LHED
|
||||
; ADD HL,SP
|
||||
; LD D,(HL)
|
||||
; INC HL
|
||||
; LD E,(HL)
|
||||
; INC HL
|
||||
; PUSH DE
|
||||
; LD D,(HL)
|
||||
; INC HL
|
||||
; LD E,(HL)
|
||||
; LD A,CMD17 ; Send CMD17 to read a sector.
|
||||
; POP HL
|
||||
; EX DE,HL
|
||||
; CALL SDCMD
|
||||
; LD A,(SDBUF+6) ; Fetch result and store.
|
||||
; AND A
|
||||
; JP NZ,READP_4
|
||||
;
|
||||
; LD HL,1000 ; Sit in a tight loop waiting for the data packet arrival (ie. not 0xFF).
|
||||
;READP_7: PUSH HL
|
||||
; LD HL,200
|
||||
; CALL T_DELAY
|
||||
; CALL SPIIN
|
||||
; POP HL
|
||||
; CP 255
|
||||
; JP NZ,READP_6
|
||||
; DEC HL
|
||||
; LD A,H
|
||||
; OR L
|
||||
; JR NZ,READP_7
|
||||
;
|
||||
;READP_6: CP 254
|
||||
; JP NZ,READP_4
|
||||
; LD HL,4
|
||||
; ADD HL,SP
|
||||
; LD E,(HL)
|
||||
; INC HL
|
||||
; LD D,(HL)
|
||||
; LD HL,514
|
||||
; AND A
|
||||
; SBC HL,DE
|
||||
; EX DE,HL
|
||||
; POP BC
|
||||
; POP HL
|
||||
; PUSH HL
|
||||
; PUSH BC
|
||||
; EX DE,HL
|
||||
; AND A
|
||||
; SBC HL,DE
|
||||
; LD (BYTECNT),HL
|
||||
;
|
||||
; LD HL,4
|
||||
; ADD HL,SP
|
||||
; LD A,(HL)
|
||||
; INC HL
|
||||
; LD H,(HL)
|
||||
; LD L,A
|
||||
; LD A,H
|
||||
; OR L
|
||||
; JP Z,READP_11
|
||||
;
|
||||
; PUSH HL
|
||||
; POP BC
|
||||
; CALL SPISKIP
|
||||
;
|
||||
;READP_11: LD HL,10 ; Get the buffer pointer from where to read data.
|
||||
; ADD HL,SP
|
||||
; LD A,(HL)
|
||||
; INC HL
|
||||
; LD H,(HL)
|
||||
; LD L,A
|
||||
; LD A,H
|
||||
; OR L
|
||||
; JP Z,READP_12
|
||||
;
|
||||
;READP_15: PUSH HL
|
||||
; CALL SPIIN
|
||||
; POP HL
|
||||
; LD (HL),A
|
||||
; INC HL
|
||||
; PUSH HL
|
||||
; POP BC
|
||||
;
|
||||
; LD HL,10 ; Update the pointer on the stack with register copy.
|
||||
; ADD HL,SP
|
||||
; LD (HL),C
|
||||
; INC HL
|
||||
; LD (HL),B
|
||||
;READP_13: POP DE ; Return address.
|
||||
; POP HL ; Count
|
||||
; DEC HL ; Decrement count
|
||||
; PUSH HL ; And return stack to previous state.
|
||||
; PUSH DE
|
||||
; LD A,H
|
||||
; OR L
|
||||
; PUSH BC
|
||||
; POP HL
|
||||
; JP NZ,READP_15
|
||||
;
|
||||
;READP_12: LD HL,(BYTECNT)
|
||||
; PUSH HL
|
||||
; POP BC
|
||||
; CALL SPISKIP
|
||||
; LD A,0
|
||||
; LD (RESULT),A
|
||||
;READP_4:
|
||||
; LD A,0
|
||||
; CALL SPICS
|
||||
; LD A,(RESULT)
|
||||
; RET
|
||||
|
||||
|
||||
; ; 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.
|
||||
; ;
|
||||
; ; 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.
|
||||
; ; Output: A = 0 - All ok. A > 0 - error occurred.
|
||||
;SD_WRITEP: LD A,1
|
||||
; LD (RESULT),A
|
||||
;
|
||||
; LD A,0FFH ; Activate CS (set low).
|
||||
; CALL SPICS
|
||||
;
|
||||
; LD HL,6 ; If buffer is not null, we are writing data, otherwise we are instigating a write transaction.
|
||||
; ADD HL,SP
|
||||
; LD A,(HL)
|
||||
; INC HL
|
||||
; LD H,(HL)
|
||||
; LD L,A
|
||||
; LD A,H
|
||||
; OR L
|
||||
; JP Z,WRITEP_3 ; NULL so we are performing a transaction open/close.
|
||||
;
|
||||
; LD HL,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.
|
||||
;
|
||||
;WRITEP_4: LD A,H ; So long as we have bytes in the buffer, send to the card for writing.
|
||||
; OR L
|
||||
; JP Z,WRITEP_5
|
||||
; LD HL,(WRITECNT) ; Count of bytes to write.
|
||||
; LD A,H
|
||||
; OR L
|
||||
; JR Z,WRITEP_5 ; If either the max count (512) or the requested count (BYTECNT) have expired, exit.
|
||||
;
|
||||
; LD HL,6 ; Load the buffer pointer.
|
||||
; ADD HL,SP
|
||||
; INC (HL)
|
||||
; LD A,(HL)
|
||||
; INC HL
|
||||
; JR NZ,WRITEP_2 ; Increment by 1 carrying overflow into MSB.
|
||||
; INC (HL)
|
||||
;WRITEP_2: LD H,(HL)
|
||||
; LD L,A
|
||||
; DEC HL ; Back to current byte.
|
||||
; LD A,(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
|
||||
; JP WRITEP_4
|
||||
;
|
||||
;WRITEP_5: LD A,0
|
||||
; LD (RESULT),A
|
||||
; JP WRITEP_8
|
||||
;
|
||||
;WRITEP_3: LD HL,2 ; Get the sector number into DEHL to test.
|
||||
; ADD HL,SP
|
||||
; LD E,(HL)
|
||||
; INC HL
|
||||
; LD D,(HL)
|
||||
; INC HL
|
||||
; LD A,(HL)
|
||||
; INC HL
|
||||
; LD H,(HL)
|
||||
; LD L,A
|
||||
; EX DE,HL
|
||||
; LD A,H
|
||||
; OR L
|
||||
; OR D
|
||||
; OR E
|
||||
; JP Z,WRITEP_9 ; Sector is 0 so finalise the write transaction.
|
||||
;
|
||||
; LD HL,(SDCAP) ; Check to see if the card has block addressing.
|
||||
; LD H,0
|
||||
; LD A,CT_BLOCK
|
||||
; AND L
|
||||
; JP NZ,WRITEP_10 ; If it hasnt then we need to multiply up to the correct byte.
|
||||
;
|
||||
; LD HL,2 + 2 ; Fetch the sector number, multiply (by left shift x 9) x512 and store.
|
||||
; CALL LBATOADDR
|
||||
;
|
||||
; ; A = ACMD to send
|
||||
; ; LHED = Argument, ie. ACMD = A, L, H, E, D, CRC
|
||||
;WRITEP_10: LD HL,2 ; Sector is stored as 3rd paramneter at offset 6, retrieve and arrange in little endian order in LHED
|
||||
; ADD HL,SP
|
||||
; LD D,(HL)
|
||||
; INC HL
|
||||
; LD E,(HL)
|
||||
; INC HL
|
||||
; PUSH DE
|
||||
; LD D,(HL)
|
||||
; INC HL
|
||||
; LD E,(HL)
|
||||
; LD A,CMD24 ; Send CMD24 to write a sector.
|
||||
; POP HL
|
||||
; EX DE,HL
|
||||
; CALL SDCMD
|
||||
; LD A,(SDBUF+6) ; Fetch result and store.
|
||||
; AND A
|
||||
; JP NZ,WRITEP_8
|
||||
; LD A,255
|
||||
; CALL SPIOUT
|
||||
; LD A,254
|
||||
; CALL SPIOUT
|
||||
; LD HL,SD_SECSIZE
|
||||
; LD (WRITECNT),HL
|
||||
; LD A,0
|
||||
; LD (RESULT),A
|
||||
; JP WRITEP_8
|
||||
;
|
||||
;WRITEP_9: LD HL,(WRITECNT)
|
||||
; INC HL
|
||||
; INC HL
|
||||
; LD (BYTECNT),HL
|
||||
;WRITEP_13:
|
||||
; LD HL,(BYTECNT)
|
||||
; DEC HL
|
||||
; LD (BYTECNT),HL
|
||||
; INC HL
|
||||
; LD A,H
|
||||
; OR L
|
||||
; JP Z,WRITEP_14
|
||||
; LD A,0
|
||||
; CALL SPIOUT
|
||||
; JP WRITEP_13
|
||||
;WRITEP_14:
|
||||
; CALL SPIIN
|
||||
; AND 01FH
|
||||
; LD L,A
|
||||
; LD H,0
|
||||
; CP 5
|
||||
; JP NZ,WRITEP_15
|
||||
;
|
||||
; LD HL,10000
|
||||
; PUSH HL
|
||||
; JR WRITEP_18
|
||||
;WRITEP_20: DEC HL
|
||||
; PUSH HL
|
||||
; LD HL,200
|
||||
; CALL T_DELAY
|
||||
;WRITEP_18: CALL SPIIN
|
||||
; POP HL
|
||||
; CP 255
|
||||
; JP Z,WRITEP_17
|
||||
; LD A,H
|
||||
; OR L
|
||||
; JR NZ,WRITEP_20
|
||||
;
|
||||
;WRITEP_17: LD A,H
|
||||
; OR L
|
||||
; JP Z,WRITEP_15
|
||||
; LD A,0
|
||||
; LD (RESULT),HL
|
||||
;WRITEP_15: LD A,000H
|
||||
; CALL SPICS
|
||||
;WRITEP_8: LD A,(RESULT)
|
||||
; RET
|
||||
|
||||
|
||||
; Method to read a sector or partial sector contents to an SD Card.
|
||||
;
|
||||
@@ -1003,6 +701,23 @@ SD_WRITE15: LD A,000H ; Disab
|
||||
SD_WRITE8: LD A,(RESULT) ; Return result.
|
||||
RET
|
||||
|
||||
; 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.
|
||||
@@ -1016,27 +731,32 @@ PRTDIR: PUSH BC
|
||||
;
|
||||
LD A,(SCRNMODE)
|
||||
CP 0
|
||||
LD H,46
|
||||
LD H,47
|
||||
JR Z,PRTDIR0
|
||||
LD H,92
|
||||
PRTDIR0: LD A,(TMPLINECNT) ; Pause if we fill the screen.
|
||||
LD H,93
|
||||
PRTDIR0: LD A,(TMPLINECNT) ; Pause if we fill the screen.
|
||||
LD E,A
|
||||
INC E
|
||||
CP H
|
||||
JR NZ,PRTNOWAIT
|
||||
LD E, 0
|
||||
PRTDIRWAIT: CALL ?KEY
|
||||
JR Z,PRTDIRWAIT
|
||||
PRTDIRWAIT: CALL GETKY
|
||||
CP ' '
|
||||
JR Z,PRTNOWAIT
|
||||
CP 'X' ; Exit from listing.
|
||||
LD A,001H
|
||||
JR Z,PRTDIR4
|
||||
JR PRTDIRWAIT
|
||||
PRTNOWAIT: LD A,E
|
||||
LD (TMPLINECNT),A
|
||||
;
|
||||
LD A, D ; Print out file number and increment.
|
||||
LD A, D ; Print out file number and increment.
|
||||
CALL PRTHX
|
||||
LD A, '.'
|
||||
CALL PRNT
|
||||
POP DE
|
||||
PUSH DE ; Get pointer to the file name and print.
|
||||
RST 018h
|
||||
PUSH DE ; Get pointer to the file name and print.
|
||||
CALL PRTFN ; Print out the filename.
|
||||
;
|
||||
LD HL, (DSPXY)
|
||||
;
|
||||
@@ -1045,11 +765,11 @@ PRTNOWAIT: LD A,E
|
||||
LD A,20
|
||||
JR C, PRTDIR2
|
||||
;
|
||||
LD A,(SCRNMODE) ; 40 Char mode? 2 columns of filenames displayed so NL.
|
||||
LD A,(SCRNMODE) ; 40 Char mode? 2 columns of filenames displayed so NL.
|
||||
CP 0
|
||||
JR Z,PRTDIR1
|
||||
;
|
||||
LD A,L ; 80 Char mode we print 4 columns of filenames.
|
||||
LD A,L ; 80 Char mode we print 4 columns of filenames.
|
||||
CP 40
|
||||
LD A,40
|
||||
JR C, PRTDIR2
|
||||
@@ -1063,7 +783,9 @@ PRTDIR1: CALL NL
|
||||
JR PRTDIR3
|
||||
PRTDIR2: LD L,A
|
||||
LD (DSPXY),HL
|
||||
PRTDIR3: POP HL
|
||||
PRTDIR3: XOR A
|
||||
PRTDIR4: OR A
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
RET
|
||||
@@ -1096,7 +818,8 @@ GETSDDIRENT:PUSH BC
|
||||
LD HL,0
|
||||
LD (SDSTARTSEC),HL
|
||||
LD (SDOFFSET),HL
|
||||
LD B,0
|
||||
LD B,C
|
||||
LD C,0
|
||||
LD (SDSTARTSEC+2),BC
|
||||
LD HL,SD_SECSIZE
|
||||
LD (SDLOADSIZE),HL
|
||||
@@ -1164,10 +887,11 @@ DIRSD2: LD A,(HL)
|
||||
BIT 7,A ; Is this entry active, ie. Bit 7 of lower flag = 1?
|
||||
JR Z,DIRSD3
|
||||
CALL PRTDIR ; Valid entry so print directory number and name pointed to by HL.
|
||||
JR NZ,DIRSD4
|
||||
INC D
|
||||
DIRSD3: INC E ; Onto next directory entry number.
|
||||
DJNZ DIRSD1
|
||||
RET
|
||||
DIRSD4: RET
|
||||
;
|
||||
|
||||
; Load a program from the SD Card into RAM and/or execute it - Part 2.
|
||||
@@ -1241,13 +965,18 @@ LOADSD9: POP DE ; No lo
|
||||
LD L,A
|
||||
LD A,(HL)
|
||||
LD (ATRB),A ; Type of file, store in the tape header memory.
|
||||
INC L
|
||||
INC HL
|
||||
LD DE,NAME
|
||||
LD BC,SDDIR_FNSZ
|
||||
LDIR ; Copy the filename into the CMT area.
|
||||
LD D,(HL)
|
||||
LD E,(HL)
|
||||
INC HL
|
||||
LD E,(HL) ; Start sector.
|
||||
LD D,(HL) ; Start sector upper 16 bits, big endian.
|
||||
INC HL
|
||||
LD (SDSTARTSEC),DE
|
||||
LD E,(HL)
|
||||
INC HL
|
||||
LD D,(HL) ; Start sector lower 16 bits, big endian.
|
||||
INC HL
|
||||
LD (COMNT),DE
|
||||
LD (SDSTARTSEC+2),DE
|
||||
@@ -1272,20 +1001,19 @@ LOADSD10: LD (DTADR),DE
|
||||
LD D,(HL) ; Execution address, store in tape header memory.
|
||||
LD (EXADR),DE
|
||||
LD DE,0
|
||||
LD (SDSTARTSEC),DE
|
||||
LD (SDOFFSET),DE
|
||||
;
|
||||
LD DE,MSGSDLOAD
|
||||
RST 018H
|
||||
LD DE,NAME
|
||||
RST 018H
|
||||
CALL PRTFN
|
||||
CALL NL
|
||||
;
|
||||
LOADSD11: LD A,(SDLOADSIZE+1)
|
||||
CP 002H
|
||||
LD HL,SD_SECSIZE ; A full sector read if remaining bytes >=512
|
||||
JR NC,LOADSD12
|
||||
LD HL,(SDLOADSIZE) ; Get remaining bytes size.
|
||||
LD HL,(SDLOADSIZE) ; Get remaining bytes size.
|
||||
LOADSD12: LD (SDBYTECNT),HL
|
||||
DI
|
||||
CALL SD_READ ; Read the sector.
|
||||
@@ -1339,13 +1067,81 @@ LOADSDERR: LD DE,MSGSDRERR
|
||||
LD A,2
|
||||
JR LOADSDX1
|
||||
|
||||
; 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.
|
||||
;
|
||||
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
|
||||
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.
|
||||
INC HL
|
||||
CP 00Dh ; end code
|
||||
JR NZ,SAVESD1
|
||||
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
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
;--------------------------------------
|
||||
;
|
||||
; Message table
|
||||
;
|
||||
;--------------------------------------
|
||||
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
|
||||
|
||||
@@ -32,12 +32,12 @@ COLW EQU 40
|
||||
SCRNSZ EQU COLW * ROW
|
||||
MODE80C EQU 0
|
||||
|
||||
;======================================
|
||||
;===========================================================
|
||||
;
|
||||
; USER ROM BANK 3
|
||||
; USER ROM BANK 3 - Monitor memory and help utilities.
|
||||
;
|
||||
;======================================
|
||||
ORG 0E800h
|
||||
;===========================================================
|
||||
ORG UROMADDR
|
||||
|
||||
;--------------------------------
|
||||
; Common code spanning all banks.
|
||||
@@ -106,339 +106,254 @@ BKSWRET3: POP BC
|
||||
|
||||
|
||||
|
||||
MEMTEST: LD B,240 ; Number of loops
|
||||
LOOP: LD HL,MEMSTART ; Start of checked memory,
|
||||
LD D,0CFh ; End memory check CF00
|
||||
LOOP1: LD A,000h
|
||||
CP L
|
||||
JR NZ,LOOP1b
|
||||
CALL PRTHL ; Print HL as 4digit hex.
|
||||
LD A,0C4h ; Move cursor left.
|
||||
LD E,004h ; 4 times.
|
||||
LOOP1a: CALL DPCT
|
||||
DEC E
|
||||
JR NZ,LOOP1a
|
||||
LOOP1b: INC HL
|
||||
LD A,H
|
||||
CP D ; Have we reached end of memory.
|
||||
JR Z,LOOP3 ; Yes, exit.
|
||||
LD A,(HL) ; Read memory location under test, ie. 0.
|
||||
CPL ; Subtract, ie. FF - A, ie FF - 0 = FF.
|
||||
LD (HL),A ; Write it back, ie. FF.
|
||||
SUB (HL) ; Subtract written memory value from A, ie. should be 0.
|
||||
JR NZ,LOOP2 ; Not zero, we have an error.
|
||||
LD A,(HL) ; Reread memory location, ie. FF
|
||||
CPL ; Subtract FF - FF
|
||||
LD (HL),A ; Write 0
|
||||
SUB (HL) ; Subtract 0
|
||||
JR Z,LOOP1 ; Loop if the same, ie. 0
|
||||
LOOP2: LD A,16h
|
||||
CALL PRNT ; Print A
|
||||
CALL PRTHX ; Print HL as 4 digit hex.
|
||||
CALL PRNTS ; Print space.
|
||||
XOR A
|
||||
LD (HL),A
|
||||
LD A,(HL) ; Get into A the failing bits.
|
||||
CALL PRTHX ; Print A as 2 digit hex.
|
||||
CALL PRNTS ; Print space.
|
||||
LD A,0FFh ; Repeat but first load FF into memory
|
||||
LD (HL),A
|
||||
LD A,(HL)
|
||||
CALL PRTHX ; Print A as 2 digit hex.
|
||||
NOP
|
||||
JR LOOP4
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF MEMORY CMDLINE TOOLS FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
LOOP3: CALL PRTHL
|
||||
LD DE,OKCHECK
|
||||
CALL MSG ; Print check message in DE
|
||||
LD A,B ; Print loop count.
|
||||
CALL PRTHX
|
||||
LD DE,OKMSG
|
||||
CALL MSG ; Print ok message in DE
|
||||
CALL NL
|
||||
DEC B
|
||||
JR NZ,LOOP
|
||||
LD DE,DONEMSG
|
||||
CALL MSG ; Print check message in DE
|
||||
JP ST1X
|
||||
;
|
||||
; Memory correction
|
||||
; command 'M'
|
||||
;
|
||||
MCORX: CALL GETHEX ; correction address
|
||||
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 A,(DE)
|
||||
CP 00Dh ; not correction
|
||||
JR Z,MCRX2
|
||||
CALL _2HEX ; ACCHL(ASCII)
|
||||
JR C,MCORX1
|
||||
LD (HL),A ; data correct
|
||||
MCRX2: INC HL
|
||||
JR MCORX1
|
||||
MCRX3: LD H,B ; memory address
|
||||
LD L,C
|
||||
JR MCORX1
|
||||
|
||||
LOOP4: LD B,09h
|
||||
CALL PRNTS ; Print space.
|
||||
XOR A ; Zero A
|
||||
SCF ; Set Carry
|
||||
LOOP5: PUSH AF ; Store A and Flags
|
||||
LD (HL),A ; Store 0 to bad location.
|
||||
LD A,(HL) ; Read back
|
||||
CALL PRTHX ; Print A as 2 digit hex.
|
||||
CALL PRNTS ; Print space
|
||||
POP AF ; Get back A (ie. 0 + C)
|
||||
RLA ; Rotate left A. Bit LSB becomes Carry (ie. 1 first instance), Carry becomes MSB
|
||||
DJNZ LOOP5 ; Loop if not zero, ie. print out all bit locations written and read to memory to locate bad bit.
|
||||
XOR A ; Zero A, clears flags.
|
||||
LD A,80h
|
||||
LD B,08h
|
||||
LOOP6: PUSH AF ; Repeat above but AND memory location with original A (ie. 80)
|
||||
LD C,A ; Basically walk through all the bits to find which one is stuck.
|
||||
LD (HL),A
|
||||
LD A,(HL)
|
||||
AND C
|
||||
NOP
|
||||
JR Z,LOOP8 ; If zero then print out the bit number
|
||||
NOP
|
||||
NOP
|
||||
LD A,C
|
||||
CPL
|
||||
LD (HL),A
|
||||
LD A,(HL)
|
||||
AND C
|
||||
JR NZ,LOOP8 ; As above, if the compliment doesnt yield zero, print out the bit number.
|
||||
LOOP7: POP AF
|
||||
RRCA
|
||||
NOP
|
||||
DJNZ LOOP6
|
||||
JP ST1X
|
||||
|
||||
LOOP8: CALL LETNL ; New line.
|
||||
LD DE,BITMSG ; BIT message
|
||||
CALL MSG ; Print message in DE
|
||||
LD A,B
|
||||
DEC A
|
||||
CALL PRTHX ; Print A as 2 digit hex, ie. BIT number.
|
||||
CALL LETNL ; New line
|
||||
LD DE,BANKMSG ; BANK message
|
||||
CALL MSG ; Print message in DE
|
||||
LD A,H
|
||||
CP 50h ; 'P'
|
||||
JR NC,LOOP9 ; Work out bank number, 1, 2 or 3.
|
||||
LD A,01h
|
||||
JR LOOP11
|
||||
|
||||
LOOP9: CP 90h
|
||||
JR NC,LOOP10
|
||||
LD A,02h
|
||||
JR LOOP11
|
||||
|
||||
LOOP10: LD A,03h
|
||||
LOOP11: CALL PRTHX ; Print A as 2 digit hex, ie. BANK number.
|
||||
JR LOOP7
|
||||
|
||||
DLY1S: PUSH AF
|
||||
PUSH BC
|
||||
LD C,10
|
||||
L0324: CALL DLY12
|
||||
DEC C
|
||||
JR NZ,L0324
|
||||
POP BC
|
||||
DUMPX: CALL GETHEX
|
||||
CALL DOT4DE
|
||||
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
|
||||
INC HL
|
||||
PUSH AF
|
||||
LD A,(DSPXY)
|
||||
ADD A,C
|
||||
LD (DSPXY),A
|
||||
POP AF
|
||||
CP 020h
|
||||
JR NC,L0D51
|
||||
LD A,02Eh
|
||||
L0D51: CALL ?ADCN
|
||||
CALL PRNT3
|
||||
LD A,(DSPXY)
|
||||
INC C
|
||||
SUB C
|
||||
LD (DSPXY),A
|
||||
DEC C
|
||||
DEC C
|
||||
DEC C
|
||||
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
|
||||
OR A
|
||||
JR Z,L0D7A
|
||||
CALL BRKEY
|
||||
JP NZ,DUM3
|
||||
L0D85: RET ; JR LEA76
|
||||
DUM4: LD HL,000A0h
|
||||
ADD HL,DE
|
||||
JR DUM1
|
||||
|
||||
; Clear memory.
|
||||
INITMEMX: LD DE,MSG_INITM
|
||||
CALL MSG
|
||||
CALL LETNL
|
||||
LD HL,1200h
|
||||
LD BC,0D000h - 1200h
|
||||
CLEAR1: LD A,00h
|
||||
LD (HL),A
|
||||
INC HL
|
||||
DEC BC
|
||||
LD A,B
|
||||
OR C
|
||||
JP NZ,CLEAR1
|
||||
RET
|
||||
|
||||
; Test the 8253 Timer, configure it as per the monitor and display the read back values.
|
||||
TIMERTST: CALL NL
|
||||
LD DE,MSG_TIMERTST
|
||||
CALL MSG
|
||||
CALL NL
|
||||
LD DE,MSG_TIMERVAL
|
||||
CALL MSG
|
||||
LD A,01h
|
||||
LD DE,8000h
|
||||
CALL TIMERTST1
|
||||
NDE: JP NDE
|
||||
JP ST1X
|
||||
TIMERTST1: DI
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
LD (AMPM),A
|
||||
LD A,0F0H
|
||||
LD (TIMFG),A
|
||||
ABCD: LD HL,0A8C0H
|
||||
XOR A
|
||||
SBC HL,DE
|
||||
PUSH HL
|
||||
INC HL
|
||||
EX DE,HL
|
||||
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),0B0H ; 10110000 Control Counter 2 10, Write 2 bytes 11, 000 Interrupt on Terminal Count, 0 16 bit binary
|
||||
LD (HL),074H ; 01110100 Control Counter 1 01, Write 2 bytes 11, 010 Rate Generator, 0 16 bit binary
|
||||
LD (HL),030H ; 00110100 Control Counter 1 01, Write 2 bytes 11, 010 interrupt on Terminal Count, 0 16 bit binary
|
||||
|
||||
LD HL,CONT2 ; Counter 2
|
||||
LD (HL),E
|
||||
LD (HL),D
|
||||
|
||||
LD HL,CONT1 ; Counter 1
|
||||
LD (HL),00AH
|
||||
LD (HL),000H
|
||||
|
||||
LD HL,CONT0 ; Counter 0
|
||||
LD (HL),00CH
|
||||
LD (HL),0C0H
|
||||
|
||||
; LD HL,CONT2 ; Counter 2
|
||||
; LD C,(HL)
|
||||
; LD A,(HL)
|
||||
; CP D
|
||||
; JP NZ,L0323H
|
||||
; LD A,C
|
||||
; CP E
|
||||
; JP Z,CDEF
|
||||
;
|
||||
|
||||
L0323H: PUSH AF
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),080H
|
||||
LD HL,CONT2 ; Counter 2
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
CALL PRNTS
|
||||
;CALL DLY1S
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),040H
|
||||
LD HL,CONT1 ; Counter 1
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
CALL PRNTS
|
||||
;CALL DLY1S
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),000H
|
||||
LD HL,CONT0 ; Counter 0
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
;CALL DLY1S
|
||||
;
|
||||
LD A,0C4h ; Move cursor left.
|
||||
LD E,0Eh ; 4 times.
|
||||
L0330: CALL DPCT
|
||||
DEC E
|
||||
JR NZ,L0330
|
||||
;
|
||||
; LD C,20
|
||||
;L0324: CALL DLY12
|
||||
; DEC C
|
||||
; JR NZ,L0324
|
||||
;
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
POP AF
|
||||
;
|
||||
LD HL,CONT2 ; Counter 2
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CP D
|
||||
JP NZ,L0323H
|
||||
LD A,C
|
||||
CP E
|
||||
JP NZ,L0323H
|
||||
;
|
||||
;
|
||||
PUSH AF
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
CALL NL
|
||||
CALL NL
|
||||
CALL NL
|
||||
LD DE,MSG_TIMERVAL2
|
||||
CALL MSG
|
||||
POP HL
|
||||
POP DE
|
||||
BGETLX: EX (SP),HL
|
||||
POP BC
|
||||
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
|
||||
|
||||
;
|
||||
CDEF: POP DE
|
||||
LD HL,CONT1
|
||||
LD (HL),00CH
|
||||
LD (HL),07BH
|
||||
INC HL
|
||||
|
||||
; INCREMENT DE REG.
|
||||
DOT4DE: INC DE
|
||||
INC DE
|
||||
INC DE
|
||||
INC DE
|
||||
RET
|
||||
|
||||
L0336H: PUSH AF
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),080H
|
||||
LD HL,CONT2 ; Counter 2
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
CALL PRNTS
|
||||
CALL DLY1S
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),040H
|
||||
LD HL,CONT1 ; Counter 1
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
CALL PRNTS
|
||||
CALL DLY1S
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),000H
|
||||
LD HL,CONT0 ; Counter 0
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
CALL DLY1S
|
||||
;
|
||||
LD A,0C4h ; Move cursor left.
|
||||
LD E,0Eh ; 4 times.
|
||||
L0340: CALL DPCT
|
||||
DEC E
|
||||
JR NZ,L0340
|
||||
;
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
POP AF
|
||||
; 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
|
||||
|
||||
LD HL,CONT2 ; Counter 2
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CP D
|
||||
JR NZ,L0336H
|
||||
LD A,C
|
||||
CP E
|
||||
JR NZ,L0336H
|
||||
CALL NL
|
||||
LD DE,MSG_TIMERVAL3
|
||||
CALL MSG
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
EI
|
||||
RET
|
||||
; 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
|
||||
;
|
||||
;
|
||||
; 1 char print to $LPT
|
||||
;
|
||||
; 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
|
||||
;
|
||||
; $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
|
||||
|
||||
;
|
||||
; RDA check
|
||||
;
|
||||
; BRKEY in to monitor return
|
||||
; in: C RDA code
|
||||
;
|
||||
RDAX: IN A,(0FEh)
|
||||
AND 00Dh
|
||||
CP C
|
||||
RET Z
|
||||
CALL BRKEY
|
||||
JR NZ,RDAX
|
||||
LD SP,ATRB
|
||||
JR ST1X2
|
||||
|
||||
; 40 CHA. IN 1 LINE CODE (DATA)
|
||||
LLPT: DB 01H ; TEXT MODE
|
||||
DB 09H
|
||||
DB 09H
|
||||
DB 0BH
|
||||
DB 0DH
|
||||
|
||||
; 80 CHA. 1 LINE CODE (DATA)
|
||||
SLPT: DB 01H ; TEXT MODE
|
||||
DB 09H
|
||||
DB 09H
|
||||
DB 09H
|
||||
DB 0DH
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF PRINTER CMDLINE TOOLS FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF HELP SCREEN FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; Simple help screen to display commands.
|
||||
HELP: CALL NL
|
||||
@@ -446,16 +361,33 @@ HELP: CALL NL
|
||||
CALL PRTSTR
|
||||
RET
|
||||
|
||||
; Modification of original MSG function, use NULL terminated strings not CR terminated.
|
||||
; 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
|
||||
CALL PRNT
|
||||
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
|
||||
@@ -471,36 +403,34 @@ HELPSCR: DB "4 - 40 COL MODE.", 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/CARD.", 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 TO LOAD CMD FOR NO EXEC.", 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 "S - SAVE CURRENT PROG 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 "V - VERIFY TAPE SAVE.", 00DH
|
||||
DB 000H
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF HELP SCREEN FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
OKCHECK: DB ", CHECK: ", 0Dh
|
||||
OKMSG: DB " OK.", 0Dh
|
||||
DONEMSG: DB 11h
|
||||
DB "RAM TEST COMPLETE.", 0Dh
|
||||
|
||||
BITMSG: DB " BIT: ", 0Dh
|
||||
BANKMSG: DB " BANK: ", 0Dh
|
||||
MSG_TIMERTST:
|
||||
DB "8253 TIMER TEST", 0Dh, 00h
|
||||
MSG_TIMERVAL:
|
||||
DB "READ VALUE 1: ", 0Dh, 00h
|
||||
MSG_TIMERVAL2:
|
||||
DB "READ VALUE 2: ", 0Dh, 00h
|
||||
MSG_TIMERVAL3:
|
||||
DB "READ DONE.", 0Dh, 00h
|
||||
|
||||
;--------------------------------------
|
||||
;
|
||||
; Message table
|
||||
;
|
||||
;--------------------------------------
|
||||
|
||||
MSG_INITM: DB "INIT MEMORY", 00DH
|
||||
|
||||
ALIGN 0EFFFh
|
||||
DB 0FFh
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
;======================================
|
||||
;===========================================================
|
||||
;
|
||||
; USER ROM BANK 4
|
||||
; USER ROM BANK 4 - CMT Controller utilities.
|
||||
;
|
||||
;======================================
|
||||
ORG 0E800h
|
||||
;===========================================================
|
||||
ORG UROMADDR
|
||||
|
||||
;--------------------------------
|
||||
; Common code spanning all banks.
|
||||
@@ -101,6 +101,198 @@ BKSWRET4: POP BC
|
||||
RET ; Return to caller.
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF CMT CONTROLLER FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; Programm load
|
||||
;
|
||||
; cmd. 'L'
|
||||
;
|
||||
LOADTAPENX: LD L,0FFH
|
||||
JR LOADTAPE1
|
||||
LOADTAPE: LD L,000H
|
||||
LOADTAPE1: PUSH HL ; Preserve auto execute flag.
|
||||
CALL ?RDI
|
||||
JP C,?ERX2
|
||||
CALL NL
|
||||
LD DE,MSG?2 ; 'LOADING '
|
||||
RST 018h
|
||||
LD DE,NAME
|
||||
RST 018h
|
||||
XOR A
|
||||
LD (BUFER),A
|
||||
LD HL,(DTADR)
|
||||
LD A,H
|
||||
OR L
|
||||
JR NZ,LE941
|
||||
LD HL,(EXADR)
|
||||
LD A,H
|
||||
OR L
|
||||
JR NZ,LE941
|
||||
LD A,0FFh
|
||||
LD (BUFER),A
|
||||
LD HL,01200h
|
||||
LD (DTADR),HL
|
||||
LE941: CALL ?RDD
|
||||
JP C,?ERX2
|
||||
POP HL ; Get back the auto execute flag.
|
||||
LD A,L
|
||||
OR A
|
||||
JR Z,LOADTAPE4 ; Dont execute.
|
||||
LD A,(BUFER)
|
||||
CP 0FFh
|
||||
JR Z,LOADTAPELM ; Execute at low memory?
|
||||
LD BC,00100h
|
||||
LD HL,(EXADR)
|
||||
JP (HL)
|
||||
LOADTAPELM: LD A,(MEMSW) ; Perform memory switch, mapping out ROM from $0000 to $C000
|
||||
LD HL,01200h ; Shift the program down to RAM at $0000
|
||||
LD DE,00000h
|
||||
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
|
||||
RET
|
||||
|
||||
VRFYX: CALL ?VRFY
|
||||
JP C,?ERX2
|
||||
LD DE,MSGOK ; 'OK!'
|
||||
RST 018h
|
||||
RET
|
||||
|
||||
SGX: LD A,(SWRK)
|
||||
RRA
|
||||
CCF
|
||||
RLA
|
||||
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
|
||||
;
|
||||
;--------------------------------------
|
||||
MSGSAVE: DB "FILENAME? ", 00DH
|
||||
|
||||
ALIGN 0EFFFh
|
||||
DB 0FFh
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
;--------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
;======================================
|
||||
;===========================================================
|
||||
;
|
||||
; USER ROM BANK 7
|
||||
; USER ROM BANK 7 - Memory and timer test utilities.
|
||||
;
|
||||
;======================================
|
||||
ORG 0E800h
|
||||
;===========================================================
|
||||
ORG UROMADDR
|
||||
|
||||
;--------------------------------
|
||||
; Common code spanning all banks.
|
||||
@@ -100,7 +100,375 @@ BKSWRET7: POP BC
|
||||
POP AF
|
||||
RET ; Return to caller.
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF MEMORY TEST FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
MEMTEST: LD B,240 ; Number of loops
|
||||
LOOP: LD HL,MEMSTART ; Start of checked memory,
|
||||
LD D,0CFh ; End memory check CF00
|
||||
LOOP1: LD A,000h
|
||||
CP L
|
||||
JR NZ,LOOP1b
|
||||
CALL PRTHL ; Print HL as 4digit hex.
|
||||
LD A,0C4h ; Move cursor left.
|
||||
LD E,004h ; 4 times.
|
||||
LOOP1a: CALL DPCT
|
||||
DEC E
|
||||
JR NZ,LOOP1a
|
||||
LOOP1b: INC HL
|
||||
LD A,H
|
||||
CP D ; Have we reached end of memory.
|
||||
JR Z,LOOP3 ; Yes, exit.
|
||||
LD A,(HL) ; Read memory location under test, ie. 0.
|
||||
CPL ; Subtract, ie. FF - A, ie FF - 0 = FF.
|
||||
LD (HL),A ; Write it back, ie. FF.
|
||||
SUB (HL) ; Subtract written memory value from A, ie. should be 0.
|
||||
JR NZ,LOOP2 ; Not zero, we have an error.
|
||||
LD A,(HL) ; Reread memory location, ie. FF
|
||||
CPL ; Subtract FF - FF
|
||||
LD (HL),A ; Write 0
|
||||
SUB (HL) ; Subtract 0
|
||||
JR Z,LOOP1 ; Loop if the same, ie. 0
|
||||
LOOP2: LD A,16h
|
||||
CALL PRNT ; Print A
|
||||
CALL PRTHX ; Print HL as 4 digit hex.
|
||||
CALL PRNTS ; Print space.
|
||||
XOR A
|
||||
LD (HL),A
|
||||
LD A,(HL) ; Get into A the failing bits.
|
||||
CALL PRTHX ; Print A as 2 digit hex.
|
||||
CALL PRNTS ; Print space.
|
||||
LD A,0FFh ; Repeat but first load FF into memory
|
||||
LD (HL),A
|
||||
LD A,(HL)
|
||||
CALL PRTHX ; Print A as 2 digit hex.
|
||||
NOP
|
||||
JR LOOP4
|
||||
|
||||
LOOP3: CALL PRTHL
|
||||
LD DE,OKCHECK
|
||||
CALL MSG ; Print check message in DE
|
||||
LD A,B ; Print loop count.
|
||||
CALL PRTHX
|
||||
LD DE,OKMSG
|
||||
CALL MSG ; Print ok message in DE
|
||||
CALL NL
|
||||
DEC B
|
||||
JR NZ,LOOP
|
||||
LD DE,DONEMSG
|
||||
CALL MSG ; Print check message in DE
|
||||
JP ST1X
|
||||
|
||||
LOOP4: LD B,09h
|
||||
CALL PRNTS ; Print space.
|
||||
XOR A ; Zero A
|
||||
SCF ; Set Carry
|
||||
LOOP5: PUSH AF ; Store A and Flags
|
||||
LD (HL),A ; Store 0 to bad location.
|
||||
LD A,(HL) ; Read back
|
||||
CALL PRTHX ; Print A as 2 digit hex.
|
||||
CALL PRNTS ; Print space
|
||||
POP AF ; Get back A (ie. 0 + C)
|
||||
RLA ; Rotate left A. Bit LSB becomes Carry (ie. 1 first instance), Carry becomes MSB
|
||||
DJNZ LOOP5 ; Loop if not zero, ie. print out all bit locations written and read to memory to locate bad bit.
|
||||
XOR A ; Zero A, clears flags.
|
||||
LD A,80h
|
||||
LD B,08h
|
||||
LOOP6: PUSH AF ; Repeat above but AND memory location with original A (ie. 80)
|
||||
LD C,A ; Basically walk through all the bits to find which one is stuck.
|
||||
LD (HL),A
|
||||
LD A,(HL)
|
||||
AND C
|
||||
NOP
|
||||
JR Z,LOOP8 ; If zero then print out the bit number
|
||||
NOP
|
||||
NOP
|
||||
LD A,C
|
||||
CPL
|
||||
LD (HL),A
|
||||
LD A,(HL)
|
||||
AND C
|
||||
JR NZ,LOOP8 ; As above, if the compliment doesnt yield zero, print out the bit number.
|
||||
LOOP7: POP AF
|
||||
RRCA
|
||||
NOP
|
||||
DJNZ LOOP6
|
||||
JP ST1X
|
||||
|
||||
LOOP8: CALL LETNL ; New line.
|
||||
LD DE,BITMSG ; BIT message
|
||||
CALL MSG ; Print message in DE
|
||||
LD A,B
|
||||
DEC A
|
||||
CALL PRTHX ; Print A as 2 digit hex, ie. BIT number.
|
||||
CALL LETNL ; New line
|
||||
LD DE,BANKMSG ; BANK message
|
||||
CALL MSG ; Print message in DE
|
||||
LD A,H
|
||||
CP 50h ; 'P'
|
||||
JR NC,LOOP9 ; Work out bank number, 1, 2 or 3.
|
||||
LD A,01h
|
||||
JR LOOP11
|
||||
|
||||
LOOP9: CP 90h
|
||||
JR NC,LOOP10
|
||||
LD A,02h
|
||||
JR LOOP11
|
||||
|
||||
LOOP10: LD A,03h
|
||||
LOOP11: CALL PRTHX ; Print A as 2 digit hex, ie. BANK number.
|
||||
JR LOOP7
|
||||
|
||||
DLY1S: PUSH AF
|
||||
PUSH BC
|
||||
LD C,10
|
||||
L0324: CALL DLY12
|
||||
DEC C
|
||||
JR NZ,L0324
|
||||
POP BC
|
||||
POP AF
|
||||
RET
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF MEMORY TEST FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; START OF TIMER TEST FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; Test the 8253 Timer, configure it as per the monitor and display the read back values.
|
||||
TIMERTST: CALL NL
|
||||
LD DE,MSG_TIMERTST
|
||||
CALL MSG
|
||||
CALL NL
|
||||
LD DE,MSG_TIMERVAL
|
||||
CALL MSG
|
||||
LD A,01h
|
||||
LD DE,8000h
|
||||
CALL TIMERTST1
|
||||
NDE: JP NDE
|
||||
JP ST1X
|
||||
TIMERTST1: DI
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
LD (AMPM),A
|
||||
LD A,0F0H
|
||||
LD (TIMFG),A
|
||||
ABCD: LD HL,0A8C0H
|
||||
XOR A
|
||||
SBC HL,DE
|
||||
PUSH HL
|
||||
INC HL
|
||||
EX DE,HL
|
||||
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),0B0H ; 10110000 Control Counter 2 10, Write 2 bytes 11, 000 Interrupt on Terminal Count, 0 16 bit binary
|
||||
LD (HL),074H ; 01110100 Control Counter 1 01, Write 2 bytes 11, 010 Rate Generator, 0 16 bit binary
|
||||
LD (HL),030H ; 00110100 Control Counter 1 01, Write 2 bytes 11, 010 interrupt on Terminal Count, 0 16 bit binary
|
||||
|
||||
LD HL,CONT2 ; Counter 2
|
||||
LD (HL),E
|
||||
LD (HL),D
|
||||
|
||||
LD HL,CONT1 ; Counter 1
|
||||
LD (HL),00AH
|
||||
LD (HL),000H
|
||||
|
||||
LD HL,CONT0 ; Counter 0
|
||||
LD (HL),00CH
|
||||
LD (HL),0C0H
|
||||
|
||||
; LD HL,CONT2 ; Counter 2
|
||||
; LD C,(HL)
|
||||
; LD A,(HL)
|
||||
; CP D
|
||||
; JP NZ,L0323H
|
||||
; LD A,C
|
||||
; CP E
|
||||
; JP Z,CDEF
|
||||
;
|
||||
|
||||
L0323H: PUSH AF
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),080H
|
||||
LD HL,CONT2 ; Counter 2
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
CALL PRNTS
|
||||
;CALL DLY1S
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),040H
|
||||
LD HL,CONT1 ; Counter 1
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
CALL PRNTS
|
||||
;CALL DLY1S
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),000H
|
||||
LD HL,CONT0 ; Counter 0
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
;CALL DLY1S
|
||||
;
|
||||
LD A,0C4h ; Move cursor left.
|
||||
LD E,0Eh ; 4 times.
|
||||
L0330: CALL DPCT
|
||||
DEC E
|
||||
JR NZ,L0330
|
||||
;
|
||||
; LD C,20
|
||||
;L0324: CALL DLY12
|
||||
; DEC C
|
||||
; JR NZ,L0324
|
||||
;
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
POP AF
|
||||
;
|
||||
LD HL,CONT2 ; Counter 2
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CP D
|
||||
JP NZ,L0323H
|
||||
LD A,C
|
||||
CP E
|
||||
JP NZ,L0323H
|
||||
;
|
||||
;
|
||||
PUSH AF
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
CALL NL
|
||||
CALL NL
|
||||
CALL NL
|
||||
LD DE,MSG_TIMERVAL2
|
||||
CALL MSG
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
POP AF
|
||||
|
||||
;
|
||||
CDEF: POP DE
|
||||
LD HL,CONT1
|
||||
LD (HL),00CH
|
||||
LD (HL),07BH
|
||||
INC HL
|
||||
|
||||
L0336H: PUSH AF
|
||||
PUSH BC
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),080H
|
||||
LD HL,CONT2 ; Counter 2
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
CALL PRNTS
|
||||
CALL DLY1S
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),040H
|
||||
LD HL,CONT1 ; Counter 1
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
CALL PRNTS
|
||||
CALL DLY1S
|
||||
;
|
||||
LD HL,CONTF ; Control Register
|
||||
LD (HL),000H
|
||||
LD HL,CONT0 ; Counter 0
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CALL PRTHX
|
||||
LD A,C
|
||||
CALL PRTHX
|
||||
;
|
||||
CALL DLY1S
|
||||
;
|
||||
LD A,0C4h ; Move cursor left.
|
||||
LD E,0Eh ; 4 times.
|
||||
L0340: CALL DPCT
|
||||
DEC E
|
||||
JR NZ,L0340
|
||||
;
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
POP AF
|
||||
|
||||
LD HL,CONT2 ; Counter 2
|
||||
LD C,(HL)
|
||||
LD A,(HL)
|
||||
CP D
|
||||
JR NZ,L0336H
|
||||
LD A,C
|
||||
CP E
|
||||
JR NZ,L0336H
|
||||
CALL NL
|
||||
LD DE,MSG_TIMERVAL3
|
||||
CALL MSG
|
||||
POP HL
|
||||
POP DE
|
||||
POP BC
|
||||
EI
|
||||
RET
|
||||
;-------------------------------------------------------------------------------
|
||||
; END OF TIMER TEST FUNCTIONALITY
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
;--------------------------------------
|
||||
;
|
||||
; Message table
|
||||
;
|
||||
;--------------------------------------
|
||||
OKCHECK: DB ", CHECK: ", 0Dh
|
||||
OKMSG: DB " OK.", 0Dh
|
||||
DONEMSG: DB 11h
|
||||
DB "RAM TEST COMPLETE.", 0Dh
|
||||
|
||||
BITMSG: DB " BIT: ", 0Dh
|
||||
BANKMSG: DB " BANK: ", 0Dh
|
||||
MSG_TIMERTST:
|
||||
DB "8253 TIMER TEST", 0Dh, 00h
|
||||
MSG_TIMERVAL:
|
||||
DB "READ VALUE 1: ", 0Dh, 00h
|
||||
MSG_TIMERVAL2:
|
||||
DB "READ VALUE 2: ", 0Dh, 00h
|
||||
MSG_TIMERVAL3:
|
||||
DB "READ DONE.", 0Dh, 00h
|
||||
|
||||
ALIGN 0EFFFh
|
||||
DB 0FFh
|
||||
|
||||
@@ -38,7 +38,7 @@ STACK: EQU 010F0H
|
||||
SPV:
|
||||
IBUFE: ; TAPE BUFFER (128 BYTES)
|
||||
ATRB: DS virtual 1 ; ATTRIBUTE
|
||||
NAME: DS virtual 17 ; FILE NAME
|
||||
NAME: DS virtual FNSIZE ; FILE NAME
|
||||
SIZE: DS virtual 2 ; BYTESIZE
|
||||
DTADR: DS virtual 2 ; DATA ADDRESS
|
||||
EXADR: DS virtual 2 ; EXECUTION ADDRESS
|
||||
@@ -135,25 +135,28 @@ RFS_COMNT: EQU 00018h ; COMME
|
||||
; the User ROM bank.
|
||||
;-----------------------------------------------
|
||||
MROMPAGES EQU 8
|
||||
USRROMPAGES EQU 12
|
||||
ROMBANK0 EQU 0
|
||||
ROMBANK1 EQU 1
|
||||
ROMBANK2 EQU 2
|
||||
ROMBANK3 EQU 3
|
||||
ROMBANK4 EQU 4
|
||||
ROMBANK5 EQU 5
|
||||
ROMBANK6 EQU 6
|
||||
ROMBANK7 EQU 7
|
||||
ROMBANK8 EQU 8
|
||||
ROMBANK9 EQU 9
|
||||
ROMBANK10 EQU 10
|
||||
ROMBANK11 EQU 11
|
||||
USRROMPAGES EQU 12 ; Monitor ROM : User ROM
|
||||
ROMBANK0 EQU 0 ; MROM SA1510 40 Char : RFS Bank 0 - Main RFS Entry point and functions.
|
||||
ROMBANK1 EQU 1 ; MROM SA1510 80 Char : RFS Bank 1 - Floppy disk controller and utilities.
|
||||
ROMBANK2 EQU 2 ; CPM 2.2 CBIOS : RFS Bank 2 - SD Card controller and utilities.
|
||||
ROMBANK3 EQU 3 ; RFS Utilities : RFS Bank 3 - Cmdline tools (Memory, Printer, Help)
|
||||
ROMBANK4 EQU 4 ; Free : RFS Bank 4 - CMT Utilities.
|
||||
ROMBANK5 EQU 5 ; Free : RFS Bank 5
|
||||
ROMBANK6 EQU 6 ; Free : RFS Bank 6
|
||||
ROMBANK7 EQU 7 ; Free : RFS Bank 7 - Memory and timer test utilities.
|
||||
ROMBANK8 EQU 8 ; : CBIOS Bank 1 - Utilities
|
||||
ROMBANK9 EQU 9 ; : CBIOS Bank 2 - Screen / ANSI Terminal
|
||||
ROMBANK10 EQU 10 ; : CBIOS Bank 3 - SD Card
|
||||
ROMBANK11 EQU 11 ; : CBIOS Bank 4 - Floppy disk controller.
|
||||
|
||||
|
||||
|
||||
PRTMZF EQU 0E880H
|
||||
MZFHDRSZ EQU 128
|
||||
RFSSECTSZ EQU 256
|
||||
MROMSIZE EQU 4096
|
||||
UROMSIZE EQU 2048
|
||||
FNSIZE EQU 17 ; Size of tape filename.
|
||||
|
||||
;ROW EQU 25
|
||||
;COLW40 EQU 80
|
||||
@@ -212,12 +215,11 @@ MFINDMZF: JP _MFINDMZF
|
||||
MROMLOAD: JP _MROMLOAD
|
||||
;-----------------------------------------
|
||||
|
||||
;
|
||||
;====================================
|
||||
;
|
||||
; ROM File System Commands
|
||||
;
|
||||
;====================================
|
||||
;====================================
|
||||
;
|
||||
; ROM File System Commands
|
||||
;
|
||||
;====================================
|
||||
|
||||
; HL contains address of block to check.
|
||||
ISMZF: PUSH BC
|
||||
@@ -230,7 +232,7 @@ ISMZF: PUSH BC
|
||||
;
|
||||
INC HL
|
||||
LD DE,NAME ; Checks to confirm this is an MZF header.
|
||||
LD B,17 ; Maximum of 17 characters, including terminator in filename.
|
||||
LD B,FNSIZE ; Maximum of 17 characters, including terminator in filename.
|
||||
ISMZFNXT: LD A,(HL)
|
||||
LD (DE),A
|
||||
CP 00Dh ; If we find a terminator then this indicates potentially a valid name.
|
||||
@@ -246,7 +248,7 @@ ISMZFNXT3: INC DE
|
||||
DJNZ ISMZFNXT
|
||||
JR ISMZFNOT ; No end of string terminator, this cant be a valid filename.
|
||||
ISMZFVFY: LD A,B
|
||||
CP 17
|
||||
CP FNSIZE
|
||||
JR Z,ISMZFNOT ; If the filename has no length it cant be valid, so loop.
|
||||
ISMZFYES: CP A ; Set zero flag to indicate match.
|
||||
ISMZFNOT: POP HL
|
||||
@@ -377,7 +379,7 @@ FINDMZF3: POP HL
|
||||
PUSH DE
|
||||
PUSH BC
|
||||
LD DE,(TMPADR) ; Original DE put onto stack, original filename into DE
|
||||
LD BC,17
|
||||
LD BC,FNSIZE
|
||||
CALL CMPSTRING
|
||||
POP BC
|
||||
POP DE
|
||||
@@ -502,11 +504,11 @@ LROMLOAD5: PUSH AF
|
||||
|
||||
|
||||
|
||||
;======================================
|
||||
;
|
||||
; SA1510 mirrored functions.
|
||||
;
|
||||
;======================================
|
||||
;======================================
|
||||
;
|
||||
; SA1510 mirrored functions.
|
||||
;
|
||||
;======================================
|
||||
|
||||
?MODE: LD HL,KEYPF
|
||||
LD (HL),08AH
|
||||
@@ -524,6 +526,14 @@ LROMLOAD5: PUSH AF
|
||||
RET
|
||||
|
||||
|
||||
;======================================
|
||||
;
|
||||
; Message table
|
||||
;
|
||||
;======================================
|
||||
|
||||
|
||||
|
||||
|
||||
; Bring in additional resources.
|
||||
USE_CMPSTRING: EQU 1
|
||||
@@ -544,9 +554,3 @@ LROMLOAD5: PUSH AF
|
||||
; Ensure we fill the entire 4K by padding with FF's.
|
||||
ALIGN 1000H
|
||||
|
||||
;
|
||||
;======================================
|
||||
;
|
||||
; Message table
|
||||
;
|
||||
;======================================
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
134
software/src/tools/Makefile
Normal file
134
software/src/tools/Makefile
Normal file
@@ -0,0 +1,134 @@
|
||||
#########################################################################################################
|
||||
##
|
||||
## Name: Makefile
|
||||
## Created: March 2020
|
||||
## Author(s): Philip Smart
|
||||
## Description: Helper tools for the MZ80A RFS upgrade
|
||||
## This makefile builds tools written in C which help with building/setting up the
|
||||
## RFS images for use in the RFS adapter.
|
||||
##
|
||||
## Credits:
|
||||
## Copyright: (c) 2020 Philip Smart <philip.smart@net2net.org>
|
||||
##
|
||||
## History: March 2020 - Initial Makefile creation
|
||||
##
|
||||
## Notes:
|
||||
##
|
||||
#########################################################################################################
|
||||
## This source file is free software: you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published
|
||||
## by the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This source file is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#########################################################################################################
|
||||
BASE =
|
||||
CC = $(BASE)gcc
|
||||
LD = $(BASE)gcc
|
||||
AS = $(BASE)as
|
||||
CP = $(BASE)objcopy
|
||||
DUMP = $(BASE)objdump
|
||||
|
||||
BASEDIR = ../../..
|
||||
SWDIR = $(BASEDIR)/software/src
|
||||
INSTALLDIR = $(BASEDIR)/software/tools
|
||||
|
||||
# we use printf from here
|
||||
COMMON_DIR = $(SWDIR)/common
|
||||
INCLUDE_DIR = $(SWDIR)/include
|
||||
|
||||
# Working directory to build object files.
|
||||
BUILD_DIR = tools_obj
|
||||
|
||||
COMMON_SRC = #$(COMMON_DIR)/sdtool.c
|
||||
COMMON_OBJ = $(patsubst $(COMMON_DIR)/%.c,$(BUILD_DIR)/%.o,$(COMMON_SRC))
|
||||
|
||||
SDTOOL_PRJ = sdtool
|
||||
SDTOOL_SRC = sdtool.c
|
||||
SDTOOL_OBJ = $(COMMON_OBJ) $(patsubst %.c,$(BUILD_DIR)/%.o,$(SDTOOL_SRC))
|
||||
|
||||
MZFDC2_PRJ = mzfdc2
|
||||
MZFDC2_SRC = mz-fdc2.c
|
||||
MZFDC2_OBJ = $(COMMON_OBJ) $(patsubst %.c,$(BUILD_DIR)/%.o,$(MZFDC2_SRC))
|
||||
|
||||
# Commandline options for each tool.
|
||||
OPTS =
|
||||
|
||||
CFLAGS = -I. -I$(COMMON_DIR) -I$(INCLUDE_DIR) -O3
|
||||
# Enable debug output.
|
||||
OFLAGS += -DDEBUG
|
||||
LFLAGS = -Wl,--gc-sections -Wl,--relax -Os
|
||||
#
|
||||
# Assembler flags.
|
||||
ASFLAGS = -I. -I$(COMMON_DIR) -I$(INCLUDE_DIR) -I$(STARTUP_DIR)
|
||||
#
|
||||
|
||||
# Our target.
|
||||
all: clean $(BUILD_DIR) $(SDTOOL_PRJ) $(MZFDC2_PRJ)
|
||||
|
||||
install: all
|
||||
cp $(SDTOOL_PRJ) $(MZFDC2_PRJ) $(INSTALLDIR)
|
||||
|
||||
clean:
|
||||
rm -f $(BUILD_DIR)/*.o *.hex *.lss *.elf *.map *.lst *.srec *~ */*.o *.bin *.srec *.dmp *.vhd *.rpt $(SDTOOL_PRJ)
|
||||
|
||||
$(SDTOOL_PRJ): $(SDTOOL_PRJ).elf $(SDTOOL_PRJ).dmp $(SDTOOL_PRJ).lss
|
||||
|
||||
$(MZFDC2_PRJ): $(MZFDC2_PRJ).elf $(MZFDC2_PRJ).dmp $(MZFDC2_PRJ).lss
|
||||
|
||||
# Convert ELF binary to bin file.
|
||||
%.bin: %.elf
|
||||
@$(CP) -O binary $< $@
|
||||
|
||||
# Convert ELF to srec format for serial upload.
|
||||
%.srec: %.elf
|
||||
@$(CP) -O srec $< $@
|
||||
|
||||
%.dmp: %.elf
|
||||
@$(DUMP) -x $< >>$@
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
# testing: option -C
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@$(DUMP) -h -S -C $< > $@
|
||||
|
||||
$(SDTOOL_PRJ): $(SDTOOL_OBJ)
|
||||
$(CC) $(LFLAGS) $(SDTOOL_OBJ) -o $@ $(LIBS)
|
||||
chmod +x $@
|
||||
|
||||
$(MZFDC2_PRJ): $(MZFDC2L_OBJ)
|
||||
$(CC) $(LFLAGS) $(MZFDC2_OBJ) -o $@ $(LIBS)
|
||||
chmod +x $@
|
||||
|
||||
# Link - this produces an ELF binary.
|
||||
$(SDTOOL_PRJ).elf: $(SDTOOL_OBJ)
|
||||
$(LD) $(LFLAGS) -o $@ $+ $(LIBS)
|
||||
|
||||
$(MZFDC2_PRJ).elf: $(MZFDC2_OBJ)
|
||||
$(LD) $(LFLAGS) -o $@ $+ $(LIBS)
|
||||
|
||||
$(BUILD_DIR)/%.o: %.c Makefile
|
||||
$(CC) $(CFLAGS) $(OFLAGS) -o $@ -c $<
|
||||
|
||||
$(BUILD_DIR)/%.o: %.cpp Makefile
|
||||
$(CC) $(CFLAGS) $(OFLAGS) -o $@ -c $<
|
||||
|
||||
$(BUILD_DIR)/%.o: $(COMMON_DIR)/%.c Makefile
|
||||
$(CC) $(CFLAGS) $(OFLAGS) -o $@ -c $<
|
||||
|
||||
$(BUILD_DIR)/%.o: %.s
|
||||
$(AS) $(ASFLAGS) -o $@ $<
|
||||
|
||||
$(BUILD_DIR)/%.o: $(STARTUP_DIR)/%.s
|
||||
$(AS) $(ASFLAGS) -o $@ $<
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir $(BUILD_DIR)
|
||||
|
||||
BIN
software/src/tools/mzfdc2
Executable file
BIN
software/src/tools/mzfdc2
Executable file
Binary file not shown.
84
software/src/tools/sdtest.c
Normal file
84
software/src/tools/sdtest.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Petit FatFs sample project for generic uC (C)ChaN, 2010 */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "pff.h"
|
||||
|
||||
|
||||
void die ( /* Stop with dying message */
|
||||
FRESULT rc /* FatFs return value */
|
||||
)
|
||||
{
|
||||
printf("Failed with rc=%u.\n", rc);
|
||||
for (;;) ;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Program Main */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
int main (void)
|
||||
{
|
||||
FATFS fatfs; /* File system object */
|
||||
DIR dir; /* Directory object */
|
||||
FILINFO fno; /* File information object */
|
||||
UINT bw, br, i;
|
||||
BYTE buff[64];
|
||||
|
||||
|
||||
printf("\nMount a volume.\n");
|
||||
rc = pf_mount(&fatfs);
|
||||
if (rc) die(rc);
|
||||
|
||||
printf("\nOpen a test file (message.txt).\n");
|
||||
rc = pf_open("MESSAGE.TXT");
|
||||
if (rc) die(rc);
|
||||
|
||||
printf("\nType the file content.\n");
|
||||
for (;;) {
|
||||
rc = pf_read(buff, sizeof(buff), &br); /* Read a chunk of file */
|
||||
if (rc || !br) break; /* Error or end of file */
|
||||
for (i = 0; i < br; i++) /* Type the data */
|
||||
putchar(buff[i]);
|
||||
}
|
||||
if (rc) die(rc);
|
||||
|
||||
#if PF_USE_WRITE
|
||||
printf("\nOpen a file to write (write.txt).\n");
|
||||
rc = pf_open("WRITE.TXT");
|
||||
if (rc) die(rc);
|
||||
|
||||
printf("\nWrite a text data. (Hello world!)\n");
|
||||
for (;;) {
|
||||
rc = pf_write("Hello world!\r\n", 14, &bw);
|
||||
if (rc || !bw) break;
|
||||
}
|
||||
if (rc) die(rc);
|
||||
|
||||
printf("\nTerminate the file write process.\n");
|
||||
rc = pf_write(0, 0, &bw);
|
||||
if (rc) die(rc);
|
||||
#endif
|
||||
|
||||
#if PF_USE_DIR
|
||||
printf("\nOpen root directory.\n");
|
||||
rc = pf_opendir(&dir, "");
|
||||
if (rc) die(rc);
|
||||
|
||||
printf("\nDirectory listing...\n");
|
||||
for (;;) {
|
||||
rc = pf_readdir(&dir, &fno); /* Read a directory item */
|
||||
if (rc || !fno.fname[0]) break; /* Error or end of dir */
|
||||
if (fno.fattrib & AM_DIR)
|
||||
printf(" <dir> %s\n", fno.fname);
|
||||
else
|
||||
printf("%8lu %s\n", fno.fsize, fno.fname);
|
||||
}
|
||||
if (rc) die(rc);
|
||||
#endif
|
||||
|
||||
printf("\nTest completed.\n");
|
||||
for (;;) ;
|
||||
}
|
||||
BIN
software/src/tools/sdtool
Executable file
BIN
software/src/tools/sdtool
Executable file
Binary file not shown.
730
software/src/tools/sdtool.c
Normal file
730
software/src/tools/sdtool.c
Normal file
@@ -0,0 +1,730 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: sdtool.c
|
||||
// Created: January 2019
|
||||
// Author(s): Philip Smart
|
||||
// Description: MZ-80A SD Card Drive file image manipulator.
|
||||
// This program creates and manipulates an SD Card image for the Sharp MZ80A with the
|
||||
// Rom Filing System addition. The image contains the Rom Filing System disk at
|
||||
// the beginning of the image (contains original Sharp MZ80A programs) along
|
||||
// with 1 or more CPM disk drive images. The resultant image is copied directly
|
||||
// onto an sd card using DD or equivalent.
|
||||
//
|
||||
// The format of the image is as follows:
|
||||
// SECTOR FUNCTION
|
||||
// 00000000 ---------------------------------------------------------------------------
|
||||
// | ROM FILING SYSTEM IMAGE |
|
||||
// | |
|
||||
// 00000000 | RFS DIRECTORY ENTRY 000 (32BYTE) |
|
||||
// | .. |
|
||||
// | .. |
|
||||
// 00001FE0 | RFS DIRECTORY ENTRY 255 (32BYTE) |
|
||||
// 00002000 ---------------------------------------------------------------------------
|
||||
// | |
|
||||
// | CP/M DISK IMAGE 1 |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// ---------------------------------------------------------------------------
|
||||
// | |
|
||||
// | CP/M DISK IMAGE 2 |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// ---------------------------------------------------------------------------
|
||||
// | |
|
||||
// | CP/M DISK IMAGE 3 |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// ---------------------------------------------------------------------------
|
||||
// | |
|
||||
// | CP/M DISK IMAGE ... |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// The Rom Filing System directory entry is based on the MZF Header format and is as follows:
|
||||
// | FLAG1 | FLAG2 | FILE NAME | START SECTOR | SIZE | LOAD ADDR | EXEC ADDR | RESERVED
|
||||
// | 1 Byte | 1 Byte | 17 Bytes | 4 Bytes | 2 Bytes | 2 Bytes | 2 Bytes | 3 Bytes
|
||||
//
|
||||
// FLAG1 : BIT 7 = 1, Valid directory entry, 0 = inactive.
|
||||
// FLAG2 : MZF Execution Code, 0x01 = Binary
|
||||
// FILENAME : Standard MZF format filename.
|
||||
// START SECTOR : Sector in the SD card where the program starts. It always starts at position 0 of the sector.
|
||||
// SIZE : Size in bytes of the program. Each file block occupies 64Kbyte space (as per a tape) and this
|
||||
// parameter provides the actual space occupied by the program at the current time.
|
||||
// LOAD ADDR : Start address in memory where data should be loaded.
|
||||
// EXEC ADDR : If a binary then this parameter specifies the location to auto execute once loaded.
|
||||
// RESERVED : Not used at the moemnt.
|
||||
//
|
||||
// Caveat: This program was just intended to be a simple helper hence not properly split into methods,
|
||||
// it may need updating as it becomes more complex!!
|
||||
//
|
||||
// Credits:
|
||||
// Copyright: (c) 2020 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: March 2020 - Initial program written.
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This source file is free software: you can redistribute it and#or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#define VERSION "1.0"
|
||||
#define RFS_MAX_DIR_ENTRIES 256
|
||||
#define RFS_DIR_ENTRY_SIZE 32
|
||||
#define RFS_DIRENT_INUSE 0x80
|
||||
#define RFS_FILESIZE 65536
|
||||
#define RFS_IMAGESIZE (RFS_FILESIZE * RFS_MAX_DIR_ENTRIES) + (RFS_DIR_ENTRY_SIZE * RFS_MAX_DIR_ENTRIES)
|
||||
#define RFS_FILEBLOCK_START (RFS_DIR_ENTRY_SIZE * RFS_MAX_DIR_ENTRIES)
|
||||
#define CPM_DRIVE_IMAGES 4
|
||||
#define CPM_SECTOR_LEN 512
|
||||
#define CPM_TRACKS 512
|
||||
#define CPM_SECTORS 32
|
||||
#define CPM_BLOCKSIZE 4096
|
||||
#define CPM_MAXDIR_ENTRIES 512
|
||||
|
||||
// Structure to represent an RFS directory entry within the RFS SD Card druve image.
|
||||
//
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t flag1;
|
||||
uint8_t flag2;
|
||||
uint8_t fileName[17];
|
||||
uint32_t startSector;
|
||||
uint16_t size;
|
||||
uint16_t loadAddr;
|
||||
uint16_t execAddr;
|
||||
uint8_t reserved[3];
|
||||
} rfs_dirent;
|
||||
|
||||
// Structure to represent an MZF header.
|
||||
//
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t ATRB;
|
||||
uint8_t NAME[17];
|
||||
uint16_t SIZE;
|
||||
uint16_t DTADR;
|
||||
uint16_t EXADR;
|
||||
uint8_t COMNT[104];
|
||||
} mzf_dirent;
|
||||
|
||||
// Mapping table from Sharp MZ80A Ascii to real Ascii.
|
||||
//
|
||||
typedef struct {
|
||||
uint8_t asciiCode;
|
||||
char asciiPrintable[6];
|
||||
} t_asciiMap;
|
||||
|
||||
static t_asciiMap asciiMap[] = {
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"}, // 0x0F
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"}, // 0x1F
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x21, "!" },
|
||||
{ 0x22, "\"" },
|
||||
{ 0x23, "#" },
|
||||
{ 0x24, "$" },
|
||||
{ 0x25, "%" },
|
||||
{ 0x26, "&" },
|
||||
{ 0x27, "'" },
|
||||
{ 0x28, "(" },
|
||||
{ 0x29, ")" },
|
||||
{ 0x2A, "*" },
|
||||
{ 0x2B, "+" },
|
||||
{ 0x2C, "," },
|
||||
{ 0x2D, "-" },
|
||||
{ 0x2E, "." },
|
||||
{ 0x2F, "/" }, // 0x2F
|
||||
{ 0x30, "0" },
|
||||
{ 0x31, "1" },
|
||||
{ 0x32, "2" },
|
||||
{ 0x33, "3" },
|
||||
{ 0x34, "4" },
|
||||
{ 0x35, "5" },
|
||||
{ 0x36, "6" },
|
||||
{ 0x37, "7" },
|
||||
{ 0x38, "8" },
|
||||
{ 0x39, "9" },
|
||||
{ 0x3A, ":" },
|
||||
{ 0x3B, ";" },
|
||||
{ 0x3C, "<" },
|
||||
{ 0x3D, "=" },
|
||||
{ 0x3E, ">" },
|
||||
{ 0x3F, "?" }, // 0x3F
|
||||
{ 0x40, "@" },
|
||||
{ 0x41, "A" },
|
||||
{ 0x42, "B" },
|
||||
{ 0x43, "C" },
|
||||
{ 0x44, "D" },
|
||||
{ 0x45, "E" },
|
||||
{ 0x46, "F" },
|
||||
{ 0x47, "G" },
|
||||
{ 0x48, "H" },
|
||||
{ 0x49, "I" },
|
||||
{ 0x4A, "J" },
|
||||
{ 0x4B, "K" },
|
||||
{ 0x4C, "L" },
|
||||
{ 0x4D, "M" },
|
||||
{ 0x4E, "N" },
|
||||
{ 0x4F, "O" }, // 0x4F
|
||||
{ 0x50, "P" },
|
||||
{ 0x51, "Q" },
|
||||
{ 0x52, "R" },
|
||||
{ 0x53, "S" },
|
||||
{ 0x54, "T" },
|
||||
{ 0x55, "U" },
|
||||
{ 0x56, "V" },
|
||||
{ 0x57, "W" },
|
||||
{ 0x58, "X" },
|
||||
{ 0x59, "Y" },
|
||||
{ 0x5A, "Z" },
|
||||
{ 0x5B, "[" },
|
||||
{ 0x5C, "\\" },
|
||||
{ 0x5D, "]" },
|
||||
{ 0x5E, "^" },
|
||||
{ 0x5F, "_" }, // 0x5F
|
||||
{ 0x20, "SPACE"}, // 0x60
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"}, // 0x6F
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"}, // 0x7F
|
||||
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"}, // 0x8F
|
||||
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x65, "e" },
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x74, "t" },
|
||||
{ 0x67, "g" },
|
||||
{ 0x68, "h" },
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x62, "b" },
|
||||
{ 0x78, "x" },
|
||||
{ 0x64, "d" },
|
||||
{ 0x72, "r" },
|
||||
{ 0x70, "p" },
|
||||
{ 0x63, "c" }, // 0x9F
|
||||
|
||||
{ 0x71, "q" },
|
||||
{ 0x61, "a" },
|
||||
{ 0x7A, "z" },
|
||||
{ 0x77, "w" },
|
||||
{ 0x73, "s" },
|
||||
{ 0x75, "u" },
|
||||
{ 0x69, "i" },
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x4F, "O" }, // O with umlaut
|
||||
{ 0x6B, "k" },
|
||||
{ 0x66, "f" },
|
||||
{ 0x76, "v" },
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x75, "u" }, // u with umlaut
|
||||
{ 0x42, "B" }, // Strasse S
|
||||
{ 0x6A, "j" }, // 0XAF
|
||||
|
||||
{ 0x6E, "n" },
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x55, "U" }, // U with umlaut
|
||||
{ 0x6D, "m" },
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x6F, "o" },
|
||||
{ 0x6C, "l" },
|
||||
{ 0x41, "A" }, // A with umlaut
|
||||
{ 0x6F, "o" }, // o with umlaut
|
||||
{ 0x61, "a" }, // a with umlaut
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x79, "y" },
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"}, // 0xBF
|
||||
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"}, // 0XCF
|
||||
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"}, // 0XDF
|
||||
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"}, // 0XEF
|
||||
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"},
|
||||
{ 0x20, "SPACE"} // 0XFF
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Simple help screen to remmber how this utility works!!
|
||||
//
|
||||
void usage(void)
|
||||
{
|
||||
printf("SDTOOL v%s\n", VERSION);
|
||||
printf("\nOptions:-\n");
|
||||
printf(" -a | --add <file> Add given file into the Image.\n");
|
||||
printf(" -b | --binary Indicate file being added is a binary file, not an MZF format file.\n");
|
||||
printf(" -c | --create-image Create or re-initialise the given image file.\n");
|
||||
printf(" -e | --exec-addr <addr> For a binary file, set the execution address to be written into the directory entry.\n");
|
||||
printf(" -h | --help This help test.\n");
|
||||
printf(" -d | --list-dir List the image directory contents.\n");
|
||||
printf(" -l | --load-addr For a binary file, set the load address to be written into the directory entry.\n");
|
||||
printf(" -i | --image <file> Image file to be created or manipulated.\n");
|
||||
printf(" -v | --verbose Output more messages.\n");
|
||||
|
||||
printf("\nExamples:\n");
|
||||
printf(" sdtool --image MZ80A_1.img --list-dir List the directory entries in the image.\n");
|
||||
printf(" sdtool --image MZ80A_1.img --create-image Initialise MZ80A_1.img to a new empty state.\n");
|
||||
printf(" sdtool --image MZ80A_1.img --add CLOCK.MZF Add the CLOCK.MZF file into the image and update the directory with the MZF header details.\n");
|
||||
printf(" sdtool --image MZ80A_1.img --add CLOCK.BIN \\\n");
|
||||
printf(" --binary \\\n");
|
||||
printf(" --exec-addr 4608 --load-addr 4608 Add the CLOCK.BIN binary file into the image with the given load and exec addresses. Update directory.\n");
|
||||
|
||||
}
|
||||
|
||||
// Method to convert a little endian <-> big endian 32bit unsigned.
|
||||
//
|
||||
uint32_t swap_endian(uint32_t value)
|
||||
{
|
||||
uint32_t b[4];
|
||||
b[0] = ((value & 0x000000ff) << 24u);
|
||||
b[1] = ((value & 0x0000ff00) << 8u);
|
||||
b[2] = ((value & 0x00ff0000) >> 8u);
|
||||
b[3] = ((value & 0xff000000) >> 24u);
|
||||
|
||||
return(b[0] | b[1] | b[2] | b[3]);
|
||||
}
|
||||
|
||||
|
||||
// Main program, to be split up into methods at a later date!! Just quick write as Im concentrating on the SD Card with RFS and CPM.
|
||||
//
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
int binary_flag = 0;
|
||||
int help_flag = 0;
|
||||
int listDir_flag = 0;
|
||||
int createImage_flag = 0;
|
||||
int verbose_flag = 0;
|
||||
uint16_t loadAddr = 0x1200;
|
||||
uint16_t execAddr = 0x1200;
|
||||
char imageFile[1024];
|
||||
char addFile[1024];
|
||||
long fileSize;
|
||||
FILE *fpImage;
|
||||
FILE *fpAdd;
|
||||
rfs_dirent rfs_directory[RFS_MAX_DIR_ENTRIES];
|
||||
mzf_dirent mzf_header;
|
||||
|
||||
// Initialise other variables.
|
||||
//
|
||||
addFile[0] = 0x00;
|
||||
imageFile[0] = 0x00;
|
||||
|
||||
// Modes of operation.
|
||||
// sdtool --add file [--binary] --image file --create-image
|
||||
// sdtool --add file [--binary] --image file
|
||||
// sdtool
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", required_argument, 0, 'a'},
|
||||
{"binary", no_argument, 0, 'b'},
|
||||
{"create-image",no_argument, 0, 'c'},
|
||||
{"exec-addr", required_argument, 0, 'e'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"list-dir", no_argument, 0, 'd'},
|
||||
{"load-addr", required_argument, 0, 'l'},
|
||||
{"image", required_argument, 0, 'i'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
// Parse the command line options.
|
||||
//
|
||||
while((opt = getopt_long(argc, argv, ":bcdha;i:l:e:", long_options, &option_index)) != -1)
|
||||
{
|
||||
switch(opt)
|
||||
{
|
||||
case 'a':
|
||||
strcpy(addFile, optarg);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
binary_flag = 1;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
createImage_flag = 1;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
listDir_flag = 1;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
execAddr = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
help_flag = 1;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
strcpy(imageFile, optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
loadAddr = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose_flag = 1;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
printf("Option %s needs a value\n", argv[optind-1]);
|
||||
break;
|
||||
case '?':
|
||||
printf("Unknown option: %s, ignoring!\n", argv[optind-1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the input.
|
||||
if(help_flag == 1)
|
||||
{
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
if(strlen(imageFile) == 0 )
|
||||
{
|
||||
printf("Image file not specified.\n");
|
||||
exit(10);
|
||||
}
|
||||
if(strlen(addFile) == 0 && listDir_flag == 0 && createImage_flag == 0)
|
||||
{
|
||||
printf("File to add not specified.\n");
|
||||
exit(11);
|
||||
}
|
||||
if(createImage_flag == 1 && listDir_flag == 1)
|
||||
{
|
||||
printf("Meaningless option, create image will result in an empty directory so no point listing the directory!!\n");
|
||||
exit(12);
|
||||
}
|
||||
|
||||
// If the create flag is set, initialise the base RFS image.
|
||||
if(createImage_flag)
|
||||
{
|
||||
fpImage = fopen(imageFile, "w");
|
||||
if(fpImage == NULL)
|
||||
{
|
||||
printf("Couldnt create the image file:%s.\n", imageFile);
|
||||
exit(30);
|
||||
} else
|
||||
{
|
||||
for(uint32_t idx=0; idx < RFS_IMAGESIZE; idx++)
|
||||
fputc(0x00, fpImage);
|
||||
}
|
||||
fclose(fpImage);
|
||||
|
||||
// All done if we are not adding a file.
|
||||
if(addFile[0] == 0x00)
|
||||
{
|
||||
if(verbose_flag)
|
||||
printf("Image file created.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Open the image file for read/write operations
|
||||
fpImage = fopen(imageFile, "r+");
|
||||
if(fpImage == NULL)
|
||||
{
|
||||
printf("Couldnt open the image file:%s.\n", imageFile);
|
||||
exit(20);
|
||||
}
|
||||
|
||||
// Get the directory into memory.
|
||||
size_t result=fread(&rfs_directory, 1, sizeof(rfs_dirent) * RFS_MAX_DIR_ENTRIES, fpImage);
|
||||
if(result < (RFS_MAX_DIR_ENTRIES * RFS_DIR_ENTRY_SIZE))
|
||||
{
|
||||
printf("Failed to read RFS directory from image, is image corrupt? (%d)\n", result);
|
||||
exit(40);
|
||||
}
|
||||
|
||||
// List directory?
|
||||
if(listDir_flag == 1)
|
||||
{
|
||||
printf("FileName Start Sector Size Load Addr Exec Addr\n");
|
||||
printf("-------- ------------ ---- --------- ---------\n");
|
||||
for(uint16_t idx=0; idx < RFS_MAX_DIR_ENTRIES; idx++)
|
||||
{
|
||||
if((rfs_directory[idx].flag1 & RFS_DIRENT_INUSE) != 0)
|
||||
{
|
||||
uint8_t canPrint = 1;
|
||||
for(uint16_t idx2=0; idx2 < 17; idx2++)
|
||||
{
|
||||
if(rfs_directory[idx].fileName[idx2] == 0x0d || rfs_directory[idx].fileName[idx2] == 0x00)
|
||||
canPrint = 0;
|
||||
|
||||
if(canPrint == 1)
|
||||
putchar(asciiMap[rfs_directory[idx].fileName[idx2]].asciiCode);
|
||||
else
|
||||
putchar(' ');
|
||||
}
|
||||
|
||||
printf(" %08lx %04x %04x %04x\n", swap_endian(rfs_directory[idx].startSector), rfs_directory[idx].size, rfs_directory[idx].loadAddr, rfs_directory[idx].execAddr);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Open the MZF file to add in read only mode.
|
||||
fpAdd = fopen(addFile, "r");
|
||||
if(fpAdd == NULL)
|
||||
{
|
||||
printf("Couldnt open the file to add:%s.\n", addFile);
|
||||
exit(21);
|
||||
}
|
||||
|
||||
// Get size of image file.
|
||||
fseek(fpImage, 0, SEEK_END);
|
||||
fileSize = ftell(fpImage);
|
||||
fseek(fpImage, 0, SEEK_SET);
|
||||
if(fileSize < RFS_IMAGESIZE)
|
||||
{
|
||||
printf("Image size is too small, please recreate with --create-image flag.\n");
|
||||
}
|
||||
|
||||
// Get size of file where adding.
|
||||
fseek(fpAdd, 0, SEEK_END);
|
||||
fileSize = ftell(fpAdd);
|
||||
fseek(fpAdd, 0, SEEK_SET);
|
||||
|
||||
// If this is an MZF file, get header.
|
||||
if(binary_flag == 0)
|
||||
{
|
||||
result=fread(&mzf_header, 1, sizeof(mzf_dirent), fpAdd);
|
||||
if(result < sizeof(mzf_dirent))
|
||||
{
|
||||
printf("Failed to read MZF header from MZF file, is image an MZF file?\n");
|
||||
exit(50);
|
||||
}
|
||||
}
|
||||
|
||||
// Locate the first empty slot to add the file.
|
||||
uint16_t dirEntry = 0;
|
||||
while((rfs_directory[dirEntry].flag1 & RFS_DIRENT_INUSE) != 0)
|
||||
{
|
||||
dirEntry++;
|
||||
if(dirEntry > 255)
|
||||
{
|
||||
printf("Image directory is full, cannot add file.\n");
|
||||
exit(60);
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, we now have a valid image file, slot in the directory which is free and the MZF file details, populate the directory entry, write it and then
|
||||
// write the file into the image.
|
||||
rfs_directory[dirEntry].flag1 = RFS_DIRENT_INUSE;
|
||||
if(binary_flag == 0)
|
||||
{
|
||||
rfs_directory[dirEntry].flag2 = mzf_header.ATRB;
|
||||
memcpy(rfs_directory[dirEntry].fileName, mzf_header.NAME, 17);
|
||||
rfs_directory[dirEntry].fileName[16] = 0x00;
|
||||
rfs_directory[dirEntry].startSector = swap_endian((RFS_FILEBLOCK_START + (dirEntry * RFS_FILESIZE))/512);;
|
||||
rfs_directory[dirEntry].size = mzf_header.SIZE;
|
||||
rfs_directory[dirEntry].loadAddr = mzf_header.DTADR;
|
||||
rfs_directory[dirEntry].execAddr = mzf_header.EXADR;
|
||||
} else
|
||||
{
|
||||
rfs_directory[dirEntry].flag2 = 0x01;
|
||||
strncpy(rfs_directory[dirEntry].fileName, addFile, 17);
|
||||
rfs_directory[dirEntry].fileName[(strlen(addFile) < 17 ? strlen(addFile) : 16)] = 0x0d;
|
||||
rfs_directory[dirEntry].startSector = swap_endian((RFS_FILEBLOCK_START + (dirEntry * RFS_FILESIZE))/512);
|
||||
rfs_directory[dirEntry].size = fileSize;
|
||||
rfs_directory[dirEntry].loadAddr = loadAddr;
|
||||
rfs_directory[dirEntry].execAddr = execAddr;
|
||||
}
|
||||
fseek(fpImage, 0, SEEK_SET);
|
||||
result=fwrite(&rfs_directory, 1, sizeof(rfs_dirent) * RFS_MAX_DIR_ENTRIES, fpImage);
|
||||
if(result < (RFS_MAX_DIR_ENTRIES * RFS_DIR_ENTRY_SIZE))
|
||||
{
|
||||
printf("Failed to write RFS directory into image file, disk full or wrong permissions?\n");
|
||||
exit(50);
|
||||
}
|
||||
|
||||
// Seek to the correct 64K block then write out 64K.
|
||||
fseek(fpImage, (RFS_FILEBLOCK_START + (dirEntry * RFS_FILESIZE)), SEEK_SET);
|
||||
for(uint32_t idx=0; idx < RFS_FILESIZE; idx++)
|
||||
{
|
||||
int c = fgetc(fpAdd);
|
||||
if(feof(fpAdd))
|
||||
c = 0xFF;
|
||||
fputc(c, fpImage);
|
||||
}
|
||||
|
||||
if(verbose_flag)
|
||||
printf("Added %s to image.\n", addFile);
|
||||
|
||||
// Tidy up, close and finish.
|
||||
fclose(fpAdd);
|
||||
fclose(fpImage);
|
||||
if(verbose_flag)
|
||||
printf("Image file updated.\n");
|
||||
}
|
||||
@@ -58,6 +58,13 @@ ROMRFS_HEADS=1
|
||||
ROMRFS_SECTORS=128
|
||||
ROMRFS_GAP3=78
|
||||
ROMRFS_INTERLEAVE=1
|
||||
|
||||
SDC16M_PATH=${CPM_PATH}/SDC16M
|
||||
SDC16M_CYLS=1024
|
||||
SDC16M_HEADS=1
|
||||
SDC16M_SECTORS=32
|
||||
SDC16M_GAP3=78
|
||||
SDC16M_INTERLEAVE=1
|
||||
#BLOCKSIZELIST="256 512 1024 4096" # List of required output files in target RFS sector size.
|
||||
BLOCKSIZELIST="128 256" # List of required output files in target RFS sector size.
|
||||
MAXIMAGESIZE=524288 # Largest expected image size (generally 1 ROM less 16K Rom Banks).
|
||||
@@ -67,6 +74,8 @@ echo "Creating CPM Disks from all the directories in:$CPM_PATH} matching this fi
|
||||
rm -f ${ROMRFS_PATH}/RAW/*.RAW
|
||||
rm -f ${FD1M44_PATH}/RAW/*.RAW
|
||||
rm -f ${FD1M44_PATH}/DSK/*.DSK
|
||||
rm -f ${SDC16M_PATH}/RAW/*.RAW
|
||||
rm -f ${SDC16M_PATH}/DSK/*.DSK
|
||||
for src in ${SOURCEDIRS}
|
||||
do
|
||||
# Different processing for the ROM RFS drives.
|
||||
@@ -98,6 +107,101 @@ echo "Creating CPM Disks from all the directories in:$CPM_PATH} matching this fi
|
||||
samdisk copy ${FD1M44_PATH}/RAW/${NEWDSKNAME}.RAW ${FD1M44_PATH}/DSK/${NEWDSKNAME}.DSK --cyls=${FD1M44_CYLS} --head=${FD1M44_HEADS} --gap3=${FD1M44_GAP3} --sectors=${FD1M44_SECTORS} --interleave=${FD1M44_INTERLEAVE}
|
||||
fi
|
||||
done
|
||||
|
||||
# Build the SD Card images, these images differ as they are larger and combine more programs in one disk under different user numbers.
|
||||
|
||||
# Copy a blank image to create the new disk.
|
||||
cp ${CPM_PATH}/BLANKFD/BLANK_16M.RAW ${SDC16M_PATH}/RAW/SDCDISK1.RAW;
|
||||
|
||||
# Copy the CPM files from the linux filesystem into the CPM Disk under the CPM filesystem.
|
||||
cp ${CPM_PATH}/BLANKFD/BLANK_16M.RAW ${SDC16M_PATH}/RAW/SDCDISK0.RAW;
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM00_SYSTEM/*.* 0:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM01_TURBOP/*.* 1:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM02_HI_C/*.* 2:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM03_FORTRAN80/*.* 3:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM04_MBASIC/*.* 4:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM05_COBOL80_v13/*.* 5:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM06_COBOL80_v20/*.* 6:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM07_COBOL80/*.* 7:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM08_Z80FORTH/*.* 8:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM09_CPMTEX/*.* 9:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM10_DISKUTILFUNC5/*.* 10:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM11_MAC80/*.* 11:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM29_ZSID_v14/*.* 12:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM32_ZCPR3/*.* 13:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK0.RAW ${CPM_PATH}/CPM33_ZCPR3_COMMON/*.* 14:
|
||||
|
||||
cp ${CPM_PATH}/BLANKFD/BLANK_16M.RAW ${SDC16M_PATH}/RAW/SDCDISK1.RAW;
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM12_PASCALMTP_v561/*.* 0:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM26_TPASCAL_v300a/*.* 1:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM13_MTPUG_01/*.* 2:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM14_MTPUG_02/*.* 3:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM15_MTPUG_03/*.* 4:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM16_MTPUG_04/*.* 5:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM17_MTPUG_05/*.* 6:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM18_MTPUG_06/*.* 7:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM19_MTPUG_07/*.* 8:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM20_MTPUG_08/*.* 9:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM21_MTPUG_09/*.* 10:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK1.RAW ${CPM_PATH}/CPM22_MTPUG_10/*.* 11:
|
||||
|
||||
cp ${CPM_PATH}/BLANKFD/BLANK_16M.RAW ${SDC16M_PATH}/RAW/SDCDISK2.RAW;
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK2.RAW ${CPM_PATH}/CPM23_PLI/*.* 0:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK2.RAW ${CPM_PATH}/CPM24_PLI80_v13/*.* 1:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK2.RAW ${CPM_PATH}/CPM25_PLI80_v14/*.* 2:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK2.RAW ${CPM_PATH}/CPM28_PLM80/*.* 3:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK2.RAW ${CPM_PATH}/CPM27_WORDSTAR_v30/*.* 4:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK2.RAW ${CPM_PATH}/CPM31_WORDSTAR_v330/*.* 5:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK2.RAW ${CPM_PATH}/CPM30_WORDSTAR_v400/*.* 6:
|
||||
|
||||
cp ${CPM_PATH}/BLANKFD/BLANK_16M.RAW ${SDC16M_PATH}/RAW/SDCDISK3.RAW;
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK3.RAW ${CPM_PATH}/CPM_MC_C0/*.* 0:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK3.RAW ${CPM_PATH}/CPM_MC_C1/*.* 1:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK3.RAW ${CPM_PATH}/CPM_MC_C2/*.* 2:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK3.RAW ${CPM_PATH}/CPM_MC_C3/*.* 3:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK3.RAW ${CPM_PATH}/CPM_MC_C4/*.* 4:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK3.RAW ${CPM_PATH}/CPM_MC_C5/*.* 5:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK3.RAW ${CPM_PATH}/CPM_MC_C6/*.* 6:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK3.RAW ${CPM_PATH}/CPM_MC_C7/*.* 7:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK3.RAW ${CPM_PATH}/CPM_MC_C8/*.* 8:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK3.RAW ${CPM_PATH}/CPM_MC_C9/*.* 9:
|
||||
|
||||
cp ${CPM_PATH}/BLANKFD/BLANK_16M.RAW ${SDC16M_PATH}/RAW/SDCDISK4.RAW;
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D0/*.* 0:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D1/*.* 1:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D2/*.* 2:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D3/*.* 3:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D4/*.* 4:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D5/*.* 5:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D6/*.* 6:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D7/*.* 7:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D8/*.* 8:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D9/*.* 9:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK4.RAW ${CPM_PATH}/CPM_MC_D9/*.* 9:
|
||||
|
||||
cp ${CPM_PATH}/BLANKFD/BLANK_16M.RAW ${SDC16M_PATH}/RAW/SDCDISK5.RAW;
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK5.RAW ${CPM_PATH}/CPM_MC_E0/*.* 0:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK5.RAW ${CPM_PATH}/CPM_MC_E1/*.* 1:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK5.RAW ${CPM_PATH}/CPM_MC_E2/*.* 2:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK5.RAW ${CPM_PATH}/CPM_MC_E3/*.* 3:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK5.RAW ${CPM_PATH}/CPM_MC_E4/*.* 4:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK5.RAW ${CPM_PATH}/CPM_MC_E5/*.* 5:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK5.RAW ${CPM_PATH}/CPM_MC_E6/*.* 6:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK5.RAW ${CPM_PATH}/CPM_MC_E7/*.* 7:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK5.RAW ${CPM_PATH}/CPM_MC_E8/*.* 8:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK5.RAW ${CPM_PATH}/CPM_MC_E9/*.* 9:
|
||||
|
||||
cp ${CPM_PATH}/BLANKFD/BLANK_16M.RAW ${SDC16M_PATH}/RAW/SDCDISK6.RAW;
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK6.RAW ${CPM_PATH}/CPM_MC_F0/*.* 0:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK6.RAW ${CPM_PATH}/CPM_MC_F1/*.* 1:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK6.RAW ${CPM_PATH}/CPM_MC_F2/*.* 2:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK6.RAW ${CPM_PATH}/CPM_MC_F3/*.* 3:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK6.RAW ${CPM_PATH}/CPM_MC_F4/*.* 4:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK6.RAW ${CPM_PATH}/CPM_MC_F5/*.* 5:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK6.RAW ${CPM_PATH}/CPM_MC_F6/*.* 6:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK6.RAW ${CPM_PATH}/CPM_MC_F7/*.* 7:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK6.RAW ${CPM_PATH}/CPM_MC_F8/*.* 8:
|
||||
cpmcp -f MZ80A-SDC16M ${SDC16M_PATH}/RAW/SDCDISK6.RAW ${CPM_PATH}/CPM_MC_F9/*.* 9:
|
||||
)
|
||||
|
||||
# Create the CPM boot image and Drive images.
|
||||
@@ -148,7 +252,7 @@ do
|
||||
done
|
||||
done </tmp/filelist
|
||||
|
||||
ls ${ROMRFS_PATH}/RAW/ ${FD1M44_PATH}/DSK/
|
||||
echo "Done, all EDSK images can be found in:${ROMRFS_PATH}/ & ${FD1M44_PATH}."
|
||||
ls ${ROMRFS_PATH}/RAW/ ${FD1M44_PATH}/DSK/ ${SDC16M_PATH}/DSK/
|
||||
echo "Done, all EDSK images can be found in:${ROMRFS_PATH}/ & ${FD1M44_PATH} & ${SDC16M_PATH}."
|
||||
|
||||
exit 0
|
||||
|
||||
310
software/tools/make_sdcard.sh
Executable file
310
software/tools/make_sdcard.sh
Executable file
@@ -0,0 +1,310 @@
|
||||
#!/bin/bash
|
||||
#########################################################################################################
|
||||
##
|
||||
## Name: make_sdcard.sh
|
||||
## Created: August 2018
|
||||
## Author(s): Philip Smart
|
||||
## Description: Sharp MZ series SD Card Packaging tool
|
||||
## This is a very basic script to package programs into images for writing onto an
|
||||
## SD Card as used in the Rom Filing System. The image is comprised of several parts,
|
||||
## ie. <RFS IMAGE> + <CPM DISK IMAGE 0> .. <CPM DIK IMAGE n>.
|
||||
##
|
||||
## Credits:
|
||||
## Copyright: (c) 2020 Philip Smart <philip.smart@net2net.org>
|
||||
##
|
||||
## History: March 2020 - Initial script written.
|
||||
##
|
||||
#########################################################################################################
|
||||
## This source file is free software: you can redistribute it and#or modify
|
||||
## it under the terms of the GNU General Public License as published
|
||||
## by the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This source file is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#########################################################################################################
|
||||
|
||||
ROOTDIR=../../MZ80A_RFS
|
||||
MZF_PATH=${ROOTDIR}/software/MZF
|
||||
TOOL_DIR=${ROOTDIR}/software/tools
|
||||
IMAGE_DIR=${ROOTDIR}/software/roms
|
||||
CPM_DIR=${ROOTDIR}/software/CPM/SDC16M/RAW
|
||||
SDTOOL=${TOOL_DIR}/sdtool
|
||||
RFS_IMAGE_FILE=${IMAGE_DIR}/SHARP_MZ80A_RFS_IMAGE_1.img
|
||||
CPM_IMAGE_FILES="SDCDISK0.RAW SDCDISK1.RAW SDCDISK2.RAW SDCDISK3.RAW SDCDISK4.RAW SDCDISK5.RAW SDCDISK6.RAW"
|
||||
SD_IMAGE_FILE=${IMAGE_DIR}/SHARP_MZ80A_RFS_CPM_IMAGE_1.img
|
||||
|
||||
# Create the initial RFS image.
|
||||
${SDTOOL} --image ${RFS_IMAGE_FILE} --create
|
||||
if [ $? != 0 ]; then
|
||||
echo "Failed to create initial RFS Image, aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Manually choose the programs you want installed into the RFS image. The files will be first placed into
|
||||
# the directory in the order they appear here, which initially is alphabetic order.
|
||||
RFS_INCLUDE=
|
||||
RFS_INCLUDE+="${MZF_PATH}/1Z-013B.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/2Z009E.MZF:"
|
||||
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:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/BASIC_MZ-5Z009_modified.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/BASIC_MZ-5Z009.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/BASIC_OM-1000.MZF:"
|
||||
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:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/COSMO_BLASTER_MZ700.MZF:"
|
||||
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:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/FDCOPY.MZT:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/FD_Editor_MZ700.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Filing(CMT).MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Filing_CMT_.MZT:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/FLAP.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/flugsim_MZ700.m12:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/fortransosz80.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/FRONT_PANEL_v1.5.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/GALAXI_FORM.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/GALAXY_INVADERS.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/GDP9-BA.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Greedy_Gremlins.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Hardcopy.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/hi-ramcheck.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HP4TMZ7L.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HP4TMZ7.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HU-BASIC.A1_M.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HU-BASIC.A1_S.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HU-BASIC.A2_80M.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HU-BASIC.A2_80S.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HU-BASIC_V1.3_K.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HUCALC_80A+_C2.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HUCALC_80A+_M.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HUCALC_80A+_S.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/hudson_basic.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/HUNCHY.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/INSTRUCS_v1.1.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/JIGSAW.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Joy.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/k-basic_v.5.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/KNIFORTH.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/KUMA_INTERPR..MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/KuPTest.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Lady_Bug_MZ80K.m12:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/LAND_ESCAPE.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Le_Mans.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/loader.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MAGIC_PAINTBOX.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MAN-HUNT.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/m_c_Breakout_2.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/m_c_Hissing_Sid.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/m_c_Race_Chase.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MEMORY_TEST.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MINI_DATACARD..MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/minotaur.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/ML-SP_8002_BBG.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/monitor2:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/monitor3.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MONITOR6.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MOVING_SEARCHER.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Mz1571.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MZ-2Z009.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/mz-5z009_modified2.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MZ700BAS.M12:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MZ700BAS.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MZ-700_FORTH.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MZ80A_basic.DSK:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/MZ-80A_GALACTIC.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Mzprint.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/nakamoto_MZ700.m12:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/NEW_INVADERS.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/OPENING_DATA.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/OTHELLO.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/PAC-MAN3.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/PAC-MAN.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/PAINFUL_MAN.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/PAINTBOX.BAS.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/PCG_BASIC_MZ700.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/PCG_BASIC.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Pcgrally_MZ800.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/PROBE_A_1200.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/PROBE_A_8000.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/PROBE_A_B600.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/QD_BAS_5Z008_MZ700.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/QDCOPY.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/RAM_CHECK_A.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/REALFORT.MZF:"
|
||||
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:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/schach2_MZ700.m12:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SCRAMBLE_A.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/sdtest.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SECTOR_R_W.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SECTOR_R_W(NEC).MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/send-1_MZ700.m12:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SEND-1.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SHARPLAN01.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/sharpmz-test.mzf:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/sharpmz-test.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SHARP_PENCIL.A1.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SHARP_PENCIL.ALF.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SLAVE_v1.1A.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/S-MASTER.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SNAKE&SNAKE_EXP1.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SNOWFLAKES.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SOLO_BASIC.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SP-4015.A1_C.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SP-4015.A1_S.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SP-5060.A1_M.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SP-5060.A1_S.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SPACE_INVADERS.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SP-CONVERT.A1.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/STKEEPER2BAS700A.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SUB-MONITOR-700.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SUCOPY_A000.A16.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SUPERFIRE.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SUPER_PUCK-MAN.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SUPERTAPE_2.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SUTAM1F.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SUTAMC9.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SUTAPEBA.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/SUTAPEMO.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/tetris-2_MZ800.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/TETRIS.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/TEXT_BASIC_I.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/TEXT~ED_v1.2.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/textsobs5.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/TRANS.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/TRANS.MZT:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/ufo.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/UNI=BASIC800.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/UNIVERSAL_BASIC.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/URAS-700.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Utility_2.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Utility.MZT:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Utility_V_1.1.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Utility_V_2.0.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/WDPRO_2.37AT_C2.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/WDPRO_2.37AT.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Wooky.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/XPATCH_5510_v2.2.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Z80_MACHINE.A1_M.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Z80_MACHINE.A1_S.MZF:"
|
||||
RFS_INCLUDE+="${MZF_PATH}/Z80_MACHINE.A2_M.MZF:"
|
||||
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}
|
||||
do
|
||||
${SDTOOL} --image ${RFS_IMAGE_FILE} --add ${f}
|
||||
if [ $? != 0 ]; then
|
||||
echo "Failed to add:${f} into the RFS Image, aborting."
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
${SDTOOL} --image ${RFS_IMAGE_FILE} --list-dir
|
||||
|
||||
# Concatenate the RFS and CPM images to make a final SD card image.
|
||||
#
|
||||
echo "Adding RFS Image:$RFS_IMAGE_FILE} to start of SD Card image."
|
||||
cat ${RFS_IMAGE_FILE} > ${SD_IMAGE_FILE}
|
||||
IFS=" "; for f in ${CPM_IMAGE_FILES}
|
||||
do
|
||||
echo "Adding CPM Drive Image:${f} to SD Card image."
|
||||
cat ${CPM_DIR}/${f} >> ${SD_IMAGE_FILE}
|
||||
done
|
||||
echo "SD Card image generated, file:${SD_IMAGE_FILE}"
|
||||
|
||||
exit 0
|
||||
BIN
software/tools/mzfdc2
Executable file
BIN
software/tools/mzfdc2
Executable file
Binary file not shown.
BIN
software/tools/sdtool
Executable file
BIN
software/tools/sdtool
Executable file
Binary file not shown.
Reference in New Issue
Block a user