tape training
This commit is contained in:
@@ -41,6 +41,9 @@ mode, or UART/CTC setup must restore it before returning.
|
|||||||
prints the low 16 bits of the sum as four hexadecimal digits. The end address
|
prints the low 16 bits of the sum as four hexadecimal digits. The end address
|
||||||
must be greater than or equal to the start address.
|
must be greater than or equal to the start address.
|
||||||
|
|
||||||
|
`D` prints 16 bytes per row followed by an ASCII column. Bytes outside the
|
||||||
|
printable ASCII range are shown as `.`.
|
||||||
|
|
||||||
Build the ROM and programmer-format images with:
|
Build the ROM and programmer-format images with:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -84,15 +87,15 @@ The outputs are:
|
|||||||
- `build/tinybasic/tinybasic.bin`: standalone relocated Tiny BASIC payload
|
- `build/tinybasic/tinybasic.bin`: standalone relocated Tiny BASIC payload
|
||||||
- `build/casette/tape_loader.bin`: standalone relocated tape-loader payload
|
- `build/casette/tape_loader.bin`: standalone relocated tape-loader payload
|
||||||
|
|
||||||
The current compact image is 12,318 bytes. Its ROM layout is:
|
The current compact image is 12,967 bytes. Its ROM layout is:
|
||||||
|
|
||||||
- `0000-007F`: reset/copy bootstrap
|
- `0000-007F`: reset/copy bootstrap
|
||||||
- `0080-1201`: packed BIOS+monitor image copied to RAM at `C000-D181`
|
- `0080-12DD`: packed BIOS+monitor image copied to RAM at `C000-D25D`
|
||||||
- `1202-13FF`: unused space reserved for the resident image to grow
|
- `12DE-13FF`: unused space reserved for the resident image to grow
|
||||||
- `1400-1C0C`: Tiny BASIC, executed directly from ROM
|
- `1400-1C0C`: Tiny BASIC, executed directly from ROM
|
||||||
- `1C0D-2FFF`: unused ROM
|
- `1C0D-2FFF`: unused ROM
|
||||||
- `3000-301D`: tape loader, executed directly from ROM
|
- `3000-32A6`: tape loader, executed directly from ROM
|
||||||
- `301E-7FFF`: unused space available for additional ROM content
|
- `32A7-7FFF`: unused space available for additional ROM content
|
||||||
|
|
||||||
The resident image starts at `C000`, its IM 2 vector table is at `C040`, and
|
The resident image starts at `C000`, its IM 2 vector table is at `C040`, and
|
||||||
linked code starts at `C080`. The bootstrap obtains the resident copy length
|
linked code starts at `C080`. The bootstrap obtains the resident copy length
|
||||||
@@ -103,8 +106,8 @@ The resulting RAM layout is:
|
|||||||
- `8000-AFFF`: Tiny BASIC workspace and BASIC program text
|
- `8000-AFFF`: Tiny BASIC workspace and BASIC program text
|
||||||
- `B000-B077`: Tiny BASIC variables and input buffer
|
- `B000-B077`: Tiny BASIC variables and input buffer
|
||||||
- `B078-BFFF`: Tiny BASIC stack space
|
- `B078-BFFF`: Tiny BASIC stack space
|
||||||
- `C000-D181`: resident BIOS, vectors, services, and monitor
|
- `C000-D25D`: resident BIOS, vectors, services, and monitor
|
||||||
- `D182-EFFF`: free space for resident-image growth
|
- `D25E-EFFF`: free space for resident-image growth
|
||||||
- `F000-FFFF`: BIOS globals, UART buffers, and monitor stack
|
- `F000-FFFF`: BIOS globals, UART buffers, and monitor stack
|
||||||
|
|
||||||
The BIOS and monitor continue to work if low ROM is disabled. ROM-resident
|
The BIOS and monitor continue to work if low ROM is disabled. ROM-resident
|
||||||
@@ -197,12 +200,14 @@ returns to the Tiny BASIC prompt.
|
|||||||
|
|
||||||
Tiny BASIC resets the stack pointer when it starts, so it does not currently
|
Tiny BASIC resets the stack pointer when it starts, so it does not currently
|
||||||
return through the monitor's `G` call. Reset the machine to return to the
|
return through the monitor's `G` call. Reset the machine to return to the
|
||||||
monitor. The tape loader occupies the later ROM slot at `3000-301D`; the first
|
monitor. The tape loader occupies the later ROM slot at `3000-32A6`; the first
|
||||||
unused byte after it is `301E`.
|
unused byte after it is `32A7`.
|
||||||
|
|
||||||
## Tape loader
|
## Tape loader
|
||||||
|
|
||||||
The tape-loader image is built from `apps/casette/tape_loader.asm`, linked at
|
The tape-loader image is built from `apps/casette/tape_loader.asm`, linked at
|
||||||
`3000`, and included in both ROM images. Start it with `T`, `TAPE`, or `G 3000`.
|
`3000`, and included in both ROM images. Start it with `T`, `TAPE`, or `G 3000`.
|
||||||
The current image polls the comparator input and prints its state through the
|
The current image polls the comparator input and prints its state through the
|
||||||
resident BIOS console service.
|
resident BIOS console service. Signal acquisition is bounded; a missing,
|
||||||
|
unstable, or permanently high signal reports `TAPE SIGNAL TIMEOUT` and returns
|
||||||
|
to the monitor instead of waiting forever with interrupts disabled.
|
||||||
|
|||||||
+2
-2
@@ -9,8 +9,8 @@ The current allocation is:
|
|||||||
|
|
||||||
- `1400-1C0C`: Tiny BASIC
|
- `1400-1C0C`: Tiny BASIC
|
||||||
- `1C0D-2FFF`: available
|
- `1C0D-2FFF`: available
|
||||||
- `3000-301D`: tape loader
|
- `3000-32A6`: tape loader
|
||||||
- `301E-7FFF`: available for more applications (`3100` is the next convenient
|
- `32A7-7FFF`: available for more applications (`3300` is the next convenient
|
||||||
aligned origin)
|
aligned origin)
|
||||||
|
|
||||||
The resident BIOS and monitor own high RAM at `C000-FFFF`. Tiny BASIC owns
|
The resident BIOS and monitor own high RAM at `C000-FFFF`. Tiny BASIC owns
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ def main() -> None:
|
|||||||
parser.add_argument("--low", type=float, default=2000.0, help="low tone in Hz")
|
parser.add_argument("--low", type=float, default=2000.0, help="low tone in Hz")
|
||||||
parser.add_argument("--high", type=float, default=4000.0, help="high tone in Hz")
|
parser.add_argument("--high", type=float, default=4000.0, help="high tone in Hz")
|
||||||
parser.add_argument("--sample-rate", type=int, default=48000)
|
parser.add_argument("--sample-rate", type=int, default=48000)
|
||||||
parser.add_argument("--leader", type=float, default=1.0, help="leader seconds")
|
parser.add_argument("--leader", type=float, default=4.0, help="leader seconds")
|
||||||
parser.add_argument("--preamble", type=int, default=64, help="number of 0x55 preamble bytes")
|
parser.add_argument("--preamble", type=int, default=64, help="number of 0x55 preamble bytes")
|
||||||
parser.add_argument("--block-size", type=int, default=64)
|
parser.add_argument("--block-size", type=int, default=64)
|
||||||
parser.add_argument("--amplitude", type=float, default=0.75)
|
parser.add_argument("--amplitude", type=float, default=0.75)
|
||||||
|
|||||||
+1029
-24
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,8 @@
|
|||||||
#define UART_CTC_CARD_BASE 0x20
|
#define UART_CTC_CARD_BASE 0x20
|
||||||
#define CTC_BASE (UART_CTC_CARD_BASE + 0x00)
|
#define CTC_BASE (UART_CTC_CARD_BASE + 0x00)
|
||||||
#define CTC_CHANNEL_0 (CTC_BASE + 0)
|
#define CTC_CHANNEL_0 (CTC_BASE + 0)
|
||||||
|
#define CTC_CHANNEL_1 (CTC_BASE + 1)
|
||||||
|
#define CTC_CHANNEL_2 (CTC_BASE + 2)
|
||||||
#define CTC_CHANNEL_3 (CTC_BASE + 3)
|
#define CTC_CHANNEL_3 (CTC_BASE + 3)
|
||||||
#define UART_BASE (UART_CTC_CARD_BASE + 0x04)
|
#define UART_BASE (UART_CTC_CARD_BASE + 0x04)
|
||||||
#define UART_CONTROL (UART_BASE + 0)
|
#define UART_CONTROL (UART_BASE + 0)
|
||||||
@@ -76,6 +78,16 @@ void bios_init(void)
|
|||||||
buffer_init(&rx_buf);
|
buffer_init(&rx_buf);
|
||||||
buffer_init(&tx_buf);
|
buffer_init(&tx_buf);
|
||||||
|
|
||||||
|
/* A CPU-only reset does not necessarily reset the external CTC. Stop and
|
||||||
|
disable every channel before rebuilding the UART clock/IRQ path. */
|
||||||
|
io_out(CTC_CHANNEL_0, 0x03);
|
||||||
|
io_out(CTC_CHANNEL_1, 0x03);
|
||||||
|
io_out(CTC_CHANNEL_2, 0x03);
|
||||||
|
io_out(CTC_CHANNEL_3, 0x03);
|
||||||
|
|
||||||
|
/* The 6850 has no reset input; CR1:CR0 = 11 is its master reset. */
|
||||||
|
io_out(UART_CONTROL, 0b00000011);
|
||||||
|
|
||||||
io_out(CTC_CHANNEL_0, 0x57);
|
io_out(CTC_CHANNEL_0, 0x57);
|
||||||
io_out(CTC_CHANNEL_0, 13);
|
io_out(CTC_CHANNEL_0, 13);
|
||||||
io_out(CTC_CHANNEL_3, 0b11001111);
|
io_out(CTC_CHANNEL_3, 0b11001111);
|
||||||
@@ -84,7 +96,6 @@ void bios_init(void)
|
|||||||
io_out(CTC_CHANNEL_0, 0x40);
|
io_out(CTC_CHANNEL_0, 0x40);
|
||||||
|
|
||||||
uart_tx_busy = 0;
|
uart_tx_busy = 0;
|
||||||
io_out(UART_CONTROL, 0b00000011);
|
|
||||||
io_out(UART_CONTROL, 0b10010101);
|
io_out(UART_CONTROL, 0b10010101);
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,6 +113,15 @@ init:
|
|||||||
di
|
di
|
||||||
ld sp, #STACK_TOP
|
ld sp, #STACK_TOP
|
||||||
|
|
||||||
|
; A reset may have interrupted a CTC service routine without executing
|
||||||
|
; RETI. Release any stale daisy-chain in-service latches before the
|
||||||
|
; channels are reinitialized. RETI acts as RET for each CALL while
|
||||||
|
; also signalling end-of-interrupt to daisy-chained peripherals.
|
||||||
|
call release_daisy_chain
|
||||||
|
call release_daisy_chain
|
||||||
|
call release_daisy_chain
|
||||||
|
call release_daisy_chain
|
||||||
|
|
||||||
call gsinit
|
call gsinit
|
||||||
|
|
||||||
; Setup interrupt mode 2
|
; Setup interrupt mode 2
|
||||||
@@ -125,6 +134,9 @@ init:
|
|||||||
hang:
|
hang:
|
||||||
jr hang
|
jr hang
|
||||||
|
|
||||||
|
release_daisy_chain:
|
||||||
|
reti
|
||||||
|
|
||||||
.area _GSINIT
|
.area _GSINIT
|
||||||
gsinit:
|
gsinit:
|
||||||
ld bc, #l__INITIALIZER
|
ld bc, #l__INITIALIZER
|
||||||
|
|||||||
@@ -131,6 +131,15 @@ static void command_dump(uint8_t argc, char **argv)
|
|||||||
print_hex8(*(volatile uint8_t *)(address + offset + column));
|
print_hex8(*(volatile uint8_t *)(address + offset + column));
|
||||||
bios_putc(' ');
|
bios_putc(' ');
|
||||||
}
|
}
|
||||||
|
for (; column < 16; ++column) {
|
||||||
|
bios_puts(" ");
|
||||||
|
}
|
||||||
|
bios_putc('|');
|
||||||
|
for (column = 0; column < row_length; ++column) {
|
||||||
|
uint8_t value = *(volatile uint8_t *)(address + offset + column);
|
||||||
|
bios_putc(value >= ' ' && value <= '~' ? (char)value : '.');
|
||||||
|
}
|
||||||
|
bios_putc('|');
|
||||||
bios_puts("\r\n");
|
bios_puts("\r\n");
|
||||||
offset += row_length;
|
offset += row_length;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user