CSRCS += devices.c main.c
DISCARD_CSRCS = discard.c devhd_discard.c
-ASRCS = trs80.s crt0.s
+ASRCS = trs80.s trs80-bank.s crt0.s
ASRCS += tricks.s commonmem.s floppy.s drivewire.s
DSRCS = ../dev/devdw.c
platform-trs80/crt0.rel
platform-trs80/commonmem.rel
platform-trs80/trs80.rel
+platform-trs80/trs80-bank.rel
start.rel
version.rel
lowlevel-z80.rel
--- /dev/null
+;
+; TRS 80 banking logic for the base Model 4 and 4P
+;
+
+ .module trs80bank
+
+ ; exported symbols
+ .globl init_hardware
+ .globl map_kernel
+ .globl map_process
+ .globl map_process_a
+ .globl map_process_always
+ .globl map_save
+ .globl map_restore
+ .globl _opreg
+ .globl _modout
+
+ ; imported symbols
+ .globl _program_vectors
+ .globl _ramsize
+ .globl _procmem
+
+ .globl s__COMMONMEM
+ .globl l__COMMONMEM
+
+ .include "kernel.def"
+ .include "../kernel.def"
+
+; -----------------------------------------------------------------------------
+; KERNEL MEMORY BANK (below 0xE800, only accessible when the kernel is mapped)
+; -----------------------------------------------------------------------------
+ .area _CODE
+
+init_hardware:
+ ; set system RAM size
+ ld hl, #128
+ ld (_ramsize), hl
+ ld hl, #(128-64) ; 64K for kernel
+ ld (_procmem), hl
+
+ ; set up interrupt vectors for the kernel (also sets up common memory in page 0x000F which is unused)
+ ld hl, #0
+ push hl
+ call _program_vectors
+ pop hl
+
+ im 1 ; set CPU interrupt mode
+
+ ; interrupt mask
+ ; 60Hz timer on
+
+ ld a, #0x24 ; 0x20 for serial
+ out (0xe0), a
+ ret
+
+
+;------------------------------------------------------------------------------
+; COMMON MEMORY PROCEDURES FOLLOW
+
+ .area _COMMONMEM
+
+opsave: .db 0x06
+_opreg: .db 0x06 ; kernel map, 80 columns
+_modout: .db 0x50 ; 80 column, sound enabled, altchars off,
+ ; external I/O enabled, 4MHz
+;
+; Mapping set up for the TRS80 4/4P
+;
+; The top 32K bank holds kernel code and pieces of common memory
+; The lower 32K is switched between the various user banks. On a
+; 4 or 4P without add in magic thats 0x62 and 0x63 mappings.
+;
+map_kernel:
+ push af
+ ld a, (_opreg)
+ and #0x8C ; keep video bits
+ or #0x02 ; map 2, base memory
+ ld (_opreg), a
+ out (0x84), a
+ pop af
+ ret
+;
+; Userspace mapping is mode 3, U64K/L32 mapped at L64K/L32
+;
+map_process:
+ ld a, h
+ or l
+ jr z, map_kernel
+map_process_hl:
+ ld a, (_opreg)
+ and #0x8C
+ or (hl) ; udata page
+ ld (_opreg), a
+ out (0x84), a
+ ret
+
+map_process_a: ; used by bankfork
+ push af
+ push bc
+ ld b, a
+ ld a, (_opreg)
+ and #0x8C
+ or b
+ ld (_opreg), a
+ out (0x84), a
+ pop bc
+ pop af
+ ret
+
+map_process_always:
+ push af
+ push hl
+ ld hl, #U_DATA__U_PAGE
+ call map_process_hl
+ pop hl
+ pop af
+ ret
+
+map_save: push af
+ ld a, (_opreg)
+ and #0x73
+ ld (opsave), a
+ pop af
+ ret
+
+map_restore:
+ push af
+ push bc
+ ld a, (opsave)
+ ld b, a
+ ld a, (_opreg)
+ and #0x8C
+ or b
+ ld (_opreg), a
+ out (0x84), a
+ pop bc
+ pop af
+ ret
+
.globl init_hardware
.globl interrupt_handler
.globl _program_vectors
- .globl map_kernel
- .globl map_process
- .globl map_process_a
- .globl map_process_always
- .globl map_save
- .globl map_restore
.globl platform_interrupt_all
- .globl _kernel_flag
; hard disk helpers
.globl _hd_xfer_in
.globl outcharhex
.globl fd_nmi_handler
.globl null_handler
+ .globl map_kernel
+ .globl map_process
+ .globl map_process_a
+ .globl map_process_always
+ .globl map_save
+ .globl map_restore
+ .globl _opreg
+ .globl _modout
.globl s__COMMONMEM
.globl l__COMMONMEM
ldir
ret
-init_hardware:
- ; set system RAM size
- ld hl, #128
- ld (_ramsize), hl
- ld hl, #(128-64) ; 64K for kernel
- ld (_procmem), hl
-
- ; set up interrupt vectors for the kernel (also sets up common memory in page 0x000F which is unused)
- ld hl, #0
- push hl
- call _program_vectors
- pop hl
-
- im 1 ; set CPU interrupt mode
-
- ; interrupt mask
- ; 60Hz timer on
-
- ld a, #0x24 ; 0x20 for serial
- out (0xe0), a
- ret
-
-
;------------------------------------------------------------------------------
; COMMON MEMORY PROCEDURES FOLLOW
.area _COMMONMEM
-opsave: .db 0x06
-_opreg: .db 0x06 ; kernel map, 80 columns
-_modout: .db 0x50 ; 80 column, sound enabled, altchars off,
- ; external I/O enabled, 4MHz
-_kernel_flag:
- .db 1 ; We start in kernel mode
-
_program_vectors:
; we are called, with interrupts disabled, by both newproc() and crt0
; will exit with interrupts off
ld (0x0066), a ; Set vector for NMI
ld hl, #fd_nmi_handler
ld (0x0067), hl
-
-;
-; Mapping set up for the TRS80 4/4P
-;
-; The top 32K bank holds kernel code and pieces of common memory
-; The lower 32K is switched between the various user banks. On a
-; 4 or 4P without add in magic thats 0x62 and 0x63 mappings.
-;
-map_kernel:
- push af
- ld a, (_opreg)
- and #0x8C ; keep video bits
- or #0x02 ; map 2, base memory
- ld (_opreg), a
- out (0x84), a
- pop af
- ret
-;
-; Userspace mapping is mode 3, U64K/L32 mapped at L64K/L32
-;
-map_process:
- ld a, h
- or l
- jr z, map_kernel
-map_process_hl:
- ld a, (_opreg)
- and #0x8C
- or (hl) ; udata page
- ld (_opreg), a
- out (0x84), a
- ret
-
-map_process_a: ; used by bankfork
- push af
- push bc
- ld b, a
- ld a, (_opreg)
- and #0x8C
- or b
- ld (_opreg), a
- out (0x84), a
- pop bc
- pop af
- ret
-
-map_process_always:
- push af
- push hl
- ld hl, #U_DATA__U_PAGE
- call map_process_hl
- pop hl
- pop af
- ret
-
-map_save: push af
- ld a, (_opreg)
- and #0x73
- ld (opsave), a
- pop af
- ret
-
-map_restore:
- push af
- push bc
- ld a, (opsave)
- ld b, a
- ld a, (_opreg)
- and #0x8C
- or b
- ld (_opreg), a
- out (0x84), a
- pop bc
- pop af
- ret
+ jp map_kernel
; outchar: Wait for UART TX idle, then print the char in A
; destroys: AF