Added start of csave command and bios write block
This commit is contained in:
+111
-1
@@ -427,7 +427,7 @@ WORDTB: .WORD PEND
|
|||||||
.WORD LIST
|
.WORD LIST
|
||||||
.WORD CLEAR
|
.WORD CLEAR
|
||||||
.WORD CLOAD
|
.WORD CLOAD
|
||||||
.WORD FCERR ; csave
|
.WORD CSAVE
|
||||||
.WORD NEW
|
.WORD NEW
|
||||||
|
|
||||||
; RESERVED WORD TOKEN VALUES
|
; RESERVED WORD TOKEN VALUES
|
||||||
@@ -4772,4 +4772,114 @@ CLNOHDRMSG: .db "HE", 0ah,0dh,00h
|
|||||||
CLBLOCKSMSG: .db " blocks", 0ah,0dh,00h
|
CLBLOCKSMSG: .db " blocks", 0ah,0dh,00h
|
||||||
CLCLRF: .db 0ah,0dh,00h
|
CLCLRF: .db 0ah,0dh,00h
|
||||||
|
|
||||||
|
CSAVE: ld a,(hl) ; get byte after "CSAVE"
|
||||||
|
cp ZTIMES ; "*" token? ("CSAVE*")
|
||||||
|
jp z,FCERR ; yes - array load (ARRLD1)
|
||||||
|
cp ZPRINT ; "?" ("PRINT token") verify
|
||||||
|
jp z,FCERR ; yes - flag "verify"
|
||||||
|
cp '#' ; 'csave#'?
|
||||||
|
jp z,CSAVEB ; yes - save binary
|
||||||
|
; just cload - load basic
|
||||||
|
jp FCERR
|
||||||
|
|
||||||
|
CSAVEB: inc hl ; skip #
|
||||||
|
push bc ; save bc
|
||||||
|
push de ; save de
|
||||||
|
CALL GETNUM ; Get start address
|
||||||
|
CALL DEINT ; Convert it to 16 bits
|
||||||
|
PUSH DE ; Save start address
|
||||||
|
CALL CHKSYN ; Make sure "," follows
|
||||||
|
.BYTE ','
|
||||||
|
CALL GETNUM ; Get length
|
||||||
|
CALL DEINT ; Convert it to 16 bits
|
||||||
|
PUSH DE ; Save length
|
||||||
|
CALL CHKSYN ; Make sure "," follows
|
||||||
|
.BYTE ','
|
||||||
|
; hl points to the first character of the string expression
|
||||||
|
call EVAL
|
||||||
|
push hl ; save command buffer pos
|
||||||
|
exx
|
||||||
|
call GETSTR
|
||||||
|
call LOADFP ; bc' = addr, e' = length
|
||||||
|
exx
|
||||||
|
pop hl ; get back command buffer pos
|
||||||
|
pop bc ; get length
|
||||||
|
pop de ; get start address
|
||||||
|
push hl
|
||||||
|
push de
|
||||||
|
call BIOS_CAS_GET_BUFFER
|
||||||
|
; hl=buffer, bc=lenght, de=start address
|
||||||
|
; Write header block
|
||||||
|
ld a,1 ; block type header
|
||||||
|
ld (hl),a
|
||||||
|
inc hl
|
||||||
|
call BYTESTOBLOCKS
|
||||||
|
push bc
|
||||||
|
ld a,b ; nr of blocks low byte
|
||||||
|
ld (hl),a
|
||||||
|
inc hl
|
||||||
|
ld a,c ; nr of blocks high byte
|
||||||
|
ld (hl),a
|
||||||
|
inc hl
|
||||||
|
push hl
|
||||||
|
exx
|
||||||
|
1$: push bc
|
||||||
|
pop hl ; get str addr to hl
|
||||||
|
ld a,(hl)
|
||||||
|
inc hl
|
||||||
|
push hl
|
||||||
|
pop bc ; get str addr+1 back into bc
|
||||||
|
pop hl ; get hl to hl'
|
||||||
|
ld (hl),a ; save character to buffer
|
||||||
|
inc hl
|
||||||
|
push hl
|
||||||
|
dec e ; count down str len
|
||||||
|
cp 0
|
||||||
|
jr nz,1$ ; repeat for the whole string
|
||||||
|
exx
|
||||||
|
pop hl ; get back buffer addr
|
||||||
|
ld a,0 ; NULL terminate string
|
||||||
|
ld (hl),a
|
||||||
|
inc hl
|
||||||
|
; Header block complete (rest of block is accepted garbage)
|
||||||
|
call BIOS_CAS_WRITE_BLOCK
|
||||||
|
|
||||||
|
pop bc ; get back block count
|
||||||
|
pop de ; get back start address
|
||||||
|
|
||||||
|
pop hl
|
||||||
|
pop de
|
||||||
|
pop bc
|
||||||
|
ret
|
||||||
|
|
||||||
|
; -------------------------------------------------------
|
||||||
|
; Convert byte count to required number of 128-byte blocks
|
||||||
|
; needs bc (length in bytes)
|
||||||
|
; returns bc (number of blocks)
|
||||||
|
; uses a
|
||||||
|
; -------------------------------------------------------
|
||||||
|
BYTESTOBLOCKS:
|
||||||
|
ld a,c
|
||||||
|
and 07fh ; remember partial-block remainder
|
||||||
|
|
||||||
|
srl b ; BC = BC / 128
|
||||||
|
rr c
|
||||||
|
srl b
|
||||||
|
rr c
|
||||||
|
srl b
|
||||||
|
rr c
|
||||||
|
srl b
|
||||||
|
rr c
|
||||||
|
srl b
|
||||||
|
rr c
|
||||||
|
srl b
|
||||||
|
rr c
|
||||||
|
srl b
|
||||||
|
rr c
|
||||||
|
|
||||||
|
or a
|
||||||
|
ret z ; exact multiple of 128
|
||||||
|
inc bc ; include partial final block
|
||||||
|
ret
|
||||||
|
|
||||||
.end
|
.end
|
||||||
|
|||||||
@@ -106,6 +106,12 @@ boot_copy:
|
|||||||
jp wait_silence
|
jp wait_silence
|
||||||
.ORG BIOS_CAS_READ_BLOCK_DRY
|
.ORG BIOS_CAS_READ_BLOCK_DRY
|
||||||
jp read_block_dry
|
jp read_block_dry
|
||||||
|
.ORG BIOS_CAS_GET_BUFFER
|
||||||
|
jp get_buffer
|
||||||
|
.ORG BIOS_CAS_WRITE_BLOCK
|
||||||
|
jp write_block
|
||||||
|
.ORG BIOS_DELAY_MS
|
||||||
|
jp delay_ms
|
||||||
|
|
||||||
; -------------------------------------------------------
|
; -------------------------------------------------------
|
||||||
; BIOS ENTRY
|
; BIOS ENTRY
|
||||||
@@ -528,6 +534,27 @@ bank:
|
|||||||
out (SYSTEM_REGISTER),a
|
out (SYSTEM_REGISTER),a
|
||||||
jr 2$
|
jr 2$
|
||||||
|
|
||||||
|
; -------------------------------------------------------
|
||||||
|
; Delay a certain miliseconds
|
||||||
|
; needs a (ms, zero returns immediately)
|
||||||
|
; uses b,c
|
||||||
|
; @1MHz each iteration takes 1000T plus 23T overhead
|
||||||
|
; -------------------------------------------------------
|
||||||
|
delay_ms:
|
||||||
|
or a ; 4T
|
||||||
|
ret z ; 5T when not taken
|
||||||
|
ld b,a ; 4T
|
||||||
|
1$:
|
||||||
|
ld c,61 ; 7T
|
||||||
|
2$:
|
||||||
|
dec c ; 4T
|
||||||
|
jr nz,2$ ; 12/7T, loop takes 971T
|
||||||
|
nop ; 4T
|
||||||
|
nop ; 4T
|
||||||
|
dec b ; 4T
|
||||||
|
jp nz,1$ ; 10T
|
||||||
|
ret
|
||||||
|
|
||||||
; -------------------------------------------------------
|
; -------------------------------------------------------
|
||||||
; Strings
|
; Strings
|
||||||
; -------------------------------------------------------
|
; -------------------------------------------------------
|
||||||
@@ -536,4 +563,4 @@ msg_header: .db "BIOS v1.0 - Joppe Blondel",00dh,00ah,000h
|
|||||||
; -------------------------------------------------------
|
; -------------------------------------------------------
|
||||||
; Other files
|
; Other files
|
||||||
; -------------------------------------------------------
|
; -------------------------------------------------------
|
||||||
#include "tape.asm"
|
#include "tape.asm"
|
||||||
|
|||||||
@@ -7,4 +7,7 @@ BIOS_ROM .equ 0c05fh
|
|||||||
BIOS_BANK .equ 0c062h
|
BIOS_BANK .equ 0c062h
|
||||||
BIOS_CAS_READ_BLOCK .equ 0c065h
|
BIOS_CAS_READ_BLOCK .equ 0c065h
|
||||||
BIOS_CAS_WAIT_SILENCE .equ 0c068h
|
BIOS_CAS_WAIT_SILENCE .equ 0c068h
|
||||||
BIOS_CAS_READ_BLOCK_DRY .equ 0c06bh
|
BIOS_CAS_READ_BLOCK_DRY .equ 0c06bh
|
||||||
|
BIOS_CAS_GET_BUFFER .equ 0c06eh
|
||||||
|
BIOS_CAS_WRITE_BLOCK .equ 0c071h
|
||||||
|
BIOS_DELAY_MS .equ 0c074h
|
||||||
@@ -557,6 +557,159 @@ wait_silence:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
; -------------------------------------------------------
|
; -------------------------------------------------------
|
||||||
|
; Return the buffer address in hl
|
||||||
|
; -------------------------------------------------------
|
||||||
|
get_buffer:
|
||||||
|
ld hl,BLOCK_BUFFER
|
||||||
|
ret
|
||||||
|
; -------------------------------------------------------
|
||||||
|
; Generate a short pulse halve
|
||||||
|
; needs d (output state)
|
||||||
|
; uses a
|
||||||
|
; before edge 20T
|
||||||
|
; after edge 402T
|
||||||
|
; -------------------------------------------------------
|
||||||
|
gen_short:
|
||||||
|
ld a,d ; 4T
|
||||||
|
xor 1 ; 7T
|
||||||
|
out (TAPE_PORT),a ; 12T
|
||||||
|
ld d,a ; 4T
|
||||||
|
ld a,18 ; 7T
|
||||||
|
1$: ; loop: 21*a
|
||||||
|
dec a ; 4T
|
||||||
|
cp 0 ; 7T
|
||||||
|
jp nz,1$ ; 10T
|
||||||
|
ret ; 10T
|
||||||
|
|
||||||
|
; -------------------------------------------------------
|
||||||
|
; Generate a long pulse
|
||||||
|
; needs d (output state)
|
||||||
|
; uses a
|
||||||
|
; before edge 20T
|
||||||
|
; after edge 801T
|
||||||
|
; -------------------------------------------------------
|
||||||
|
gen_long:
|
||||||
|
ld a,d ; 4T
|
||||||
|
xor 1 ; 7T
|
||||||
|
out (TAPE_PORT),a ; 12T
|
||||||
|
ld d,a ; 4T
|
||||||
|
ld a,37 ; 7T
|
||||||
|
1$: ; loop: 21*a
|
||||||
|
dec a ; 4T
|
||||||
|
cp 0 ; 7T
|
||||||
|
jp nz,1$ ; 10T
|
||||||
|
ret ; 10T
|
||||||
|
|
||||||
|
; -------------------------------------------------------
|
||||||
|
; Generate a bit
|
||||||
|
; needs carry (bit value)
|
||||||
|
; needs d (output state)
|
||||||
|
; uses a
|
||||||
|
; -------------------------------------------------------
|
||||||
|
gen_bit:
|
||||||
|
jr c,1$ ; carry set: generate a one
|
||||||
|
call gen_short ; zero: short, then long
|
||||||
|
jp gen_long ; tail call returns to caller
|
||||||
|
1$:
|
||||||
|
call gen_long ; one: long, then short
|
||||||
|
jp gen_short ; tail call returns to caller
|
||||||
|
|
||||||
|
; -------------------------------------------------------
|
||||||
|
; Generate a byte
|
||||||
|
; needs a (byte to generate)
|
||||||
|
; needs d (output state)
|
||||||
|
; uses a,b,c
|
||||||
|
; -------------------------------------------------------
|
||||||
|
gen_byte:
|
||||||
|
ld c,a ; preserve the byte
|
||||||
|
ld b,8 ; 8 bits
|
||||||
|
1$:
|
||||||
|
sla c ;shift bit 7 into carry
|
||||||
|
call gen_bit
|
||||||
|
djnz 1$ ; repeat till b=0
|
||||||
|
ret
|
||||||
|
|
||||||
|
; -------------------------------------------------------
|
||||||
|
; Generate the leader
|
||||||
|
; needs d (output state)
|
||||||
|
; uses a,b,c
|
||||||
|
; -------------------------------------------------------
|
||||||
|
gen_leader:
|
||||||
|
; short leader
|
||||||
|
ld b,50 ; generate 50 short pulses
|
||||||
|
1$:
|
||||||
|
call gen_short
|
||||||
|
dec b
|
||||||
|
ld a,b
|
||||||
|
cp 0
|
||||||
|
jr nz,1$ ; repeat if not done
|
||||||
|
; long leader
|
||||||
|
ld b,50 ; generate 50 long pulses
|
||||||
|
2$:
|
||||||
|
call gen_long
|
||||||
|
dec b
|
||||||
|
ld a,b
|
||||||
|
cp 0
|
||||||
|
jr nz,2$ ; repeat if not done
|
||||||
|
; marker
|
||||||
|
ld b,8 ; generate 8 short pulses
|
||||||
|
3$:
|
||||||
|
call gen_short
|
||||||
|
dec b
|
||||||
|
ld a,b
|
||||||
|
cp 0
|
||||||
|
jr nz,3$ ; repeat if not done
|
||||||
|
; training byte
|
||||||
|
ld a,055h
|
||||||
|
call gen_byte
|
||||||
|
ret
|
||||||
|
|
||||||
|
; -------------------------------------------------------
|
||||||
|
; Write a block
|
||||||
|
; Writes the block stored in the block buffer
|
||||||
|
; -------------------------------------------------------
|
||||||
|
write_block:
|
||||||
|
push de
|
||||||
|
push bc
|
||||||
|
; calculate the crc16 over the block
|
||||||
|
ld hl, BLOCK_BUFFER
|
||||||
|
ld a, BLOCK_SIZE-2 ; dont use crc value in block
|
||||||
|
call crc16
|
||||||
|
ex de,hl
|
||||||
|
ld hl, BLOCK_BUFFER+BLOCK_SIZE-2
|
||||||
|
ld (hl),de ; save crc to block
|
||||||
|
; Write the block
|
||||||
|
ld a,0 ; Start with a low output
|
||||||
|
ld d,a
|
||||||
|
out (TAPE_PORT),a
|
||||||
|
call gen_leader
|
||||||
|
; Generate synchronization bytes
|
||||||
|
ld a,05ah
|
||||||
|
call gen_byte
|
||||||
|
ld a,0c3h
|
||||||
|
call gen_byte
|
||||||
|
; write the block buffer
|
||||||
|
ld hl, BLOCK_BUFFER
|
||||||
|
ld e, BLOCK_SIZE
|
||||||
|
1$:
|
||||||
|
ld a,(hl) ; get byte from buffer
|
||||||
|
inc hl
|
||||||
|
call gen_byte
|
||||||
|
dec e
|
||||||
|
ld a,e
|
||||||
|
cp 0
|
||||||
|
jr nz,1$ ; repeat till done
|
||||||
|
; Done with buffer, write 0 byte at last
|
||||||
|
ld a,0
|
||||||
|
call gen_byte
|
||||||
|
; Generate space
|
||||||
|
ld a,200
|
||||||
|
call delay_ms
|
||||||
|
|
||||||
|
pop bc
|
||||||
|
pop de
|
||||||
|
ret
|
||||||
|
; -------------------------------------------------------
|
||||||
; Strings
|
; Strings
|
||||||
; -------------------------------------------------------
|
; -------------------------------------------------------
|
||||||
msg_start: .db "PLAY TAPE", 0ah,0dh,00h
|
msg_start: .db "PLAY TAPE", 0ah,0dh,00h
|
||||||
|
|||||||
Reference in New Issue
Block a user