New -> currentt
This commit is contained in:
@@ -0,0 +1,447 @@
|
||||
#target bin
|
||||
#include "build/memory.inc"
|
||||
#include "hardware.inc"
|
||||
#include "bios.inc"
|
||||
|
||||
CTC_BASE .equ 020h
|
||||
CTC_CHANNEL_0 .equ CTC_BASE+000h
|
||||
CTC_CHANNEL_1 .equ CTC_BASE+001h
|
||||
CTC_CHANNEL_2 .equ CTC_BASE+002h
|
||||
CTC_CHANNEL_3 .equ CTC_BASE+003h
|
||||
UART_BASE .equ 024h
|
||||
UART_CONTROL .equ UART_BASE+000h
|
||||
UART_DATA .equ UART_BASE+001h
|
||||
|
||||
BUF_SIZE .equ 16
|
||||
BUF_SIZE_MASK .equ 00fh
|
||||
|
||||
WORKSPACE .equ SHARED_MEM_START+00400h
|
||||
TX_HEAD .equ WORKSPACE+000h
|
||||
TX_TAIL .equ WORKSPACE+001h
|
||||
TX_COUNT .equ WORKSPACE+002h
|
||||
RX_HEAD .equ WORKSPACE+003h
|
||||
RX_TAIL .equ WORKSPACE+004h
|
||||
RX_COUNT .equ WORKSPACE+005h
|
||||
TX_BUSY .equ WORKSPACE+006h
|
||||
TX_BUF .equ WORKSPACE+007h
|
||||
RX_BUF .equ TX_BUF+BUF_SIZE
|
||||
|
||||
; -------------------------------------------------------
|
||||
; entry
|
||||
; -------------------------------------------------------
|
||||
#code BIOS_BOOT, ROM_START, (BIOS_ROM_START-ROM_START)
|
||||
.org 00000h
|
||||
jp boot_copy
|
||||
.org 00008h
|
||||
boot_copy:
|
||||
di
|
||||
; Make sure system reg is in its default state
|
||||
; banking enabled
|
||||
; bank 1 selected
|
||||
ld a,BOOT_BANK_MAPPING
|
||||
ld (SYSTEM_REGISTER),a
|
||||
ld sp,BIOS_STACK_TOP
|
||||
; copy bios to top 16k
|
||||
ld hl,BIOS_ROM_START
|
||||
ld de,SHARED_MEM_START
|
||||
ld bc,BIOS_size
|
||||
ldir
|
||||
; copy basic to top 16k
|
||||
ld hl,BASIC_ROM_START
|
||||
ld de,BASIC_RAM_START
|
||||
ld bc,BASIC_ROM_SIZE
|
||||
ldir
|
||||
|
||||
jp init
|
||||
|
||||
#code BIOS, SHARED_MEM_START
|
||||
#assert BIOS_size <= BIOS_ROM_SIZE
|
||||
; -------------------------------------------------------
|
||||
; Interrupt vector table
|
||||
; -------------------------------------------------------
|
||||
.org SHARED_MEM_START+000h
|
||||
jp init
|
||||
.org SHARED_MEM_START+008h
|
||||
reti
|
||||
.org SHARED_MEM_START+010h
|
||||
reti
|
||||
.org SHARED_MEM_START+018h
|
||||
reti
|
||||
.org SHARED_MEM_START+020h
|
||||
reti
|
||||
.org SHARED_MEM_START+028h
|
||||
reti
|
||||
.org SHARED_MEM_START+030h
|
||||
reti
|
||||
.org SHARED_MEM_START+038h
|
||||
reti
|
||||
.org SHARED_MEM_START+040h
|
||||
.dw ctc_isr
|
||||
.dw ctc_isr
|
||||
.dw ctc_isr
|
||||
.dw uart_isr
|
||||
|
||||
; -------------------------------------------------------
|
||||
; BIOS JUMP TABLE
|
||||
; -------------------------------------------------------
|
||||
.org BIOS_PUTC
|
||||
jp putc
|
||||
.org BIOS_GETC
|
||||
jp getc
|
||||
.org BIOS_TRY_GETC
|
||||
jp try_getc
|
||||
.org BIOS_PUTS
|
||||
jp puts
|
||||
|
||||
; -------------------------------------------------------
|
||||
; BIOS ENTRY
|
||||
; -------------------------------------------------------
|
||||
init:
|
||||
di
|
||||
ld sp,SHARED_MEM_END
|
||||
; Some im2 mode peripherals may still be 'in service'
|
||||
; force some irets to clear them
|
||||
call release_daisy_chain
|
||||
call release_daisy_chain
|
||||
call release_daisy_chain
|
||||
call release_daisy_chain
|
||||
call release_daisy_chain
|
||||
call release_daisy_chain
|
||||
call release_daisy_chain
|
||||
call release_daisy_chain
|
||||
; Setup interrupts
|
||||
ld a,0c0h ; load interrupt table
|
||||
ld i,a
|
||||
im 2
|
||||
|
||||
; Initialize tx and rx buffers
|
||||
call buffers_init
|
||||
; Initialize peripherals
|
||||
call ctc_uart_init
|
||||
ei
|
||||
|
||||
; Print header message
|
||||
ld hl,msg_header
|
||||
call puts
|
||||
|
||||
; Enter bios
|
||||
jp BASIC_RAM_START
|
||||
|
||||
; Shouldnt come here
|
||||
; just to be safe an endless loop
|
||||
0$:
|
||||
call getc
|
||||
call putc
|
||||
jr 0$
|
||||
|
||||
; -------------------------------------------------------
|
||||
; CTC interrupt
|
||||
; -------------------------------------------------------
|
||||
ctc_isr:
|
||||
ei
|
||||
reti
|
||||
|
||||
; -------------------------------------------------------
|
||||
; UART INTERRUPT
|
||||
; -------------------------------------------------------
|
||||
uart_isr:
|
||||
push af
|
||||
push bc
|
||||
push de
|
||||
push hl
|
||||
; Load status byte
|
||||
in a,(UART_CONTROL)
|
||||
ld b,a
|
||||
; Check status for rx interrupt
|
||||
ld a,b
|
||||
and 021h
|
||||
jr nz,3$ ; rx interrupt
|
||||
101$:
|
||||
; Check status for tx interrupt
|
||||
ld a,b
|
||||
and 002h
|
||||
jr nz,1$ ; tx interrupt
|
||||
100$:
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
pop af
|
||||
ei
|
||||
reti
|
||||
|
||||
1$:
|
||||
; tx interrupt, dequeue byte and transmit
|
||||
ld a,(TX_BUSY)
|
||||
cp 1
|
||||
jr nz,100$ ; not actively txing, return
|
||||
ld a,(TX_COUNT)
|
||||
cp 0
|
||||
jr z,2$ ; nothing to transmit
|
||||
; something in queue, dequeue
|
||||
ld hl,TX_BUF
|
||||
ld a,(TX_TAIL)
|
||||
ld e,a
|
||||
ld d,0
|
||||
add hl,de
|
||||
; hl contains tail of queue
|
||||
ld a,(hl)
|
||||
ld d,a
|
||||
; d contains data to transmit
|
||||
; do (tail+1)%BUF_SIZE
|
||||
ld a,e
|
||||
inc a
|
||||
and BUF_SIZE_MASK
|
||||
ld (TX_TAIL),a
|
||||
ld hl,TX_COUNT ; decrease tx count
|
||||
dec (hl)
|
||||
; transmit the byte
|
||||
ld a,d
|
||||
out (UART_DATA),a
|
||||
jr 100$
|
||||
2$:
|
||||
; Queue is empty, stop tx interrupts
|
||||
ld a,10010101b
|
||||
out (UART_CONTROL),a
|
||||
; clear tx busy flag
|
||||
ld a,0
|
||||
ld (TX_BUSY),a
|
||||
jr 100$
|
||||
3$:
|
||||
; rx interrupt
|
||||
in a,(UART_DATA)
|
||||
ld c,a
|
||||
ld a,b
|
||||
and 001h ; check status bit 0
|
||||
jr z,101$ ; status bit 0 is clear, return
|
||||
ld a,(RX_COUNT)
|
||||
cp BUF_SIZE
|
||||
jr z,101$ ; rx queue is full, return
|
||||
; enqueue byte
|
||||
ld hl,RX_BUF
|
||||
ld a,(RX_HEAD)
|
||||
ld e,a
|
||||
ld d,0
|
||||
add hl,de
|
||||
; hl contains head of queue
|
||||
ld (hl),c
|
||||
; Do (head+1)%BUFSIZE
|
||||
ld a,e
|
||||
inc a
|
||||
and BUF_SIZE_MASK
|
||||
ld (RX_HEAD),a ; Increase rx count
|
||||
ld hl,RX_COUNT
|
||||
inc (hl)
|
||||
jr 101$
|
||||
|
||||
; -------------------------------------------------------
|
||||
; Force IRET
|
||||
; -------------------------------------------------------
|
||||
release_daisy_chain:
|
||||
reti
|
||||
|
||||
; -------------------------------------------------------
|
||||
; Initialize CTC and UART
|
||||
; -------------------------------------------------------
|
||||
ctc_uart_init:
|
||||
; Reset CTC channels
|
||||
ld a,003h
|
||||
out (CTC_CHANNEL_0),a
|
||||
out (CTC_CHANNEL_1),a
|
||||
out (CTC_CHANNEL_2),a
|
||||
out (CTC_CHANNEL_3),a
|
||||
; Reset UART
|
||||
ld a,00000011b
|
||||
out (UART_CONTROL),a
|
||||
; CTC channel 0 is timesource for uart
|
||||
ld a,057h
|
||||
out (CTC_CHANNEL_0),a
|
||||
ld a,13
|
||||
out (CTC_CHANNEL_0),a
|
||||
; CTC channel 3 is interrupt source for handler
|
||||
ld a,11001111b
|
||||
out (CTC_CHANNEL_3),a
|
||||
ld a ,1
|
||||
out (CTC_CHANNEL_3),a
|
||||
; set im2 vector for CTC
|
||||
ld a,000h
|
||||
out (CTC_CHANNEL_0),a
|
||||
ld a,040h
|
||||
out (CTC_CHANNEL_0),a
|
||||
; Initialise UART
|
||||
ld a,10010101b
|
||||
out (UART_CONTROL),a
|
||||
ret
|
||||
|
||||
; -------------------------------------------------------
|
||||
; Initialize TX and RX queues
|
||||
; -------------------------------------------------------
|
||||
buffers_init:
|
||||
ld a,00h
|
||||
ld (TX_HEAD),a
|
||||
ld (TX_TAIL),a
|
||||
ld (TX_COUNT),a
|
||||
ld (RX_HEAD),a
|
||||
ld (RX_TAIL),a
|
||||
ld (RX_COUNT),a
|
||||
ld (TX_BUSY),a
|
||||
ret
|
||||
|
||||
; -------------------------------------------------------
|
||||
; Kick uart to start transmission
|
||||
; uses a
|
||||
; -------------------------------------------------------
|
||||
uart_kick:
|
||||
di
|
||||
push de
|
||||
push hl
|
||||
ld a,(TX_BUSY)
|
||||
cp 0
|
||||
jr z,100$ ; not actively transmitting yet
|
||||
1$:
|
||||
pop hl
|
||||
pop de
|
||||
ei
|
||||
ret
|
||||
100$:
|
||||
ld a,(TX_COUNT)
|
||||
cp 0
|
||||
jr z,1$ ; tx queue empty, return
|
||||
ld hl,TX_BUF
|
||||
ld a,(TX_TAIL)
|
||||
ld e,a
|
||||
ld d,0
|
||||
add hl,de
|
||||
; hl contains tail of queue
|
||||
ld a,(hl)
|
||||
ld d,a
|
||||
; Do (tail+1)%BUFSIZE
|
||||
ld a,e
|
||||
inc a
|
||||
and BUF_SIZE_MASK
|
||||
ld (TX_TAIL),a
|
||||
ld hl,TX_COUNT ; Decrement tx count
|
||||
dec (hl)
|
||||
ld a,1 ; set busy flag
|
||||
ld (TX_BUSY),a
|
||||
; transmit actual data
|
||||
ld a,d
|
||||
out (UART_DATA),a
|
||||
; Enable tx interrupts
|
||||
ld a,10110101b
|
||||
out (UART_CONTROL),a
|
||||
jr 1$
|
||||
|
||||
; -------------------------------------------------------
|
||||
; Write a byte to uart
|
||||
; needs a (byte to tx)
|
||||
; -------------------------------------------------------
|
||||
putc:
|
||||
push af
|
||||
push de
|
||||
push bc
|
||||
push hl
|
||||
ld c,a
|
||||
100$:
|
||||
di
|
||||
ld b,0
|
||||
ld a,(TX_COUNT)
|
||||
cp BUF_SIZE
|
||||
jr z,1$ ; tx queue full, wait
|
||||
; enqueue data
|
||||
ld hl,TX_BUF
|
||||
ld a,(TX_HEAD)
|
||||
ld e,a
|
||||
ld d,0
|
||||
add hl,de
|
||||
; hl contains head of queue
|
||||
ld (hl),c
|
||||
; Do (head+1)%BUF_SIZE
|
||||
ld a,e
|
||||
inc a
|
||||
and BUF_SIZE_MASK
|
||||
ld (TX_HEAD),a
|
||||
ld hl,TX_COUNT ; Increment tx count
|
||||
inc (hl)
|
||||
ld b,1 ; set succeeded flag
|
||||
1$:
|
||||
ei
|
||||
ld a,b
|
||||
cp 1 ; Check if succeeded
|
||||
jr z,2$ ; tx done, kick and return
|
||||
; not succeeded, try again
|
||||
call uart_kick
|
||||
jr 100$
|
||||
2$:
|
||||
call uart_kick
|
||||
pop hl
|
||||
pop bc
|
||||
pop de
|
||||
pop af
|
||||
ret
|
||||
|
||||
; -------------------------------------------------------
|
||||
; Try to receive a byte
|
||||
; returns a (byte)
|
||||
; carry == not succeeded
|
||||
; -------------------------------------------------------
|
||||
try_getc:
|
||||
di
|
||||
push bc
|
||||
push de
|
||||
push hl
|
||||
ld a,(RX_COUNT)
|
||||
cp 0
|
||||
jr z,1$ ; rx queue empty, return
|
||||
; dequeue
|
||||
ld hl,RX_BUF
|
||||
ld a,(RX_TAIL)
|
||||
ld e,a
|
||||
ld d,0
|
||||
add hl,de
|
||||
; hl contains tail of queue
|
||||
ld a,(hl)
|
||||
ld d,a
|
||||
; Do (tail+1)%BUF_SIZE
|
||||
ld a,e
|
||||
inc a
|
||||
and BUF_SIZE_MASK
|
||||
ld (RX_TAIL),a
|
||||
ld hl,RX_COUNT ; decrement rx count
|
||||
dec (hl)
|
||||
ld a,d
|
||||
or a,a ; clear carry
|
||||
100$:
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
ei
|
||||
ret
|
||||
1$:
|
||||
scf
|
||||
jr 100$
|
||||
|
||||
; -------------------------------------------------------
|
||||
; Print a string
|
||||
; needs hl (pointer to string)
|
||||
; uses a
|
||||
; -------------------------------------------------------
|
||||
puts:
|
||||
ld a,(hl)
|
||||
cp 0
|
||||
ret z ; encountered a 0, end of string
|
||||
call putc
|
||||
inc hl
|
||||
jr puts
|
||||
|
||||
; -------------------------------------------------------
|
||||
; Get a byte, block if unavailable
|
||||
; -------------------------------------------------------
|
||||
getc:
|
||||
call try_getc
|
||||
jr c,getc
|
||||
ret
|
||||
|
||||
; -------------------------------------------------------
|
||||
; Strings
|
||||
; -------------------------------------------------------
|
||||
msg_header: .db "BIOS v1.0 - Joppe Blondel",00dh,00ah,000h
|
||||
Reference in New Issue
Block a user