Commit 0aba65f9 authored by John P. Willis's avatar John P. Willis
Browse files

Begin work on disk subsystem

parent 56cb49ab
[console]
mode=serial
port=/dev/ilxim
port=/dev/modem
bps=9600
parity=N
data_bits=8
......
......@@ -12,7 +12,7 @@
#include "console.bi"
function asm_encode_amod(ops_following as ubyte, amod as ubyte, disp as ubyte) as ubyte
function asm_encode_amod(data_type as ubyte, amod as ubyte, disp as ubyte) as ubyte
' 7 6543 210
' +-+----+---+
' |O|MOD |DSP|
......@@ -22,10 +22,10 @@ function asm_encode_amod(ops_following as ubyte, amod as ubyte, disp as ubyte) a
' 8
dim t as ubyte = 0
if ops_following = 1 then
t or= (1 shl 7)
if data_type = DT_WORD then
t or= (DT_WORD shl 7)
else
t or= (0 shl 7)
t or= (DT_BYTE shl 7)
end if
t or= (amod shl 3)
......@@ -67,7 +67,7 @@ function asm_decode_disp(disp as ubyte) as ushort
end select
end function ' asm_decode_disp()
function asm_encode_address(ops_following as ubyte, addr_string as string) as t_operand
function asm_encode_address(data_type as ubyte, addr_string as string) as t_operand
'
' xxxx immediate AM_IMM
' %ga reg direct AM_REGD
......@@ -142,33 +142,33 @@ function asm_encode_address(ops_following as ubyte, addr_string as string) as t_
end if
if is_immediate = 1 then ' immediate
amod = asm_encode_amod(ops_following, AM_IMM, displacement)
amod = asm_encode_amod(data_type, AM_IMM, displacement)
elseif is_register = 1 then
if is_indirect = 1 then
if has_displacement = 1 then ' register indirect + displacement
amod = asm_encode_amod(ops_following, AM_REGID, displacement)
amod = asm_encode_amod(data_type, AM_REGID, displacement)
else ' reigster indirect, no displacement
amod = asm_encode_amod(ops_following, AM_REGI, displacement)
amod = asm_encode_amod(data_type, AM_REGI, displacement)
end if
else
if has_displacement = 1 then ' register direct + displacement
amod = asm_encode_amod(ops_following, AM_REGDD, displacement)
amod = asm_encode_amod(data_type, AM_REGDD, displacement)
else ' register direct, no displacement
amod = asm_encode_amod(ops_following, AM_REGD, displacement)
amod = asm_encode_amod(data_type, AM_REGD, displacement)
end if
end if
elseif is_memory = 1 then
if is_indirect = 1 then
if has_displacement = 1 then ' memory indirect + displacement
amod = asm_encode_amod(ops_following, AM_MEMID, displacement)
amod = asm_encode_amod(data_type, AM_MEMID, displacement)
else ' memory indirect, no displacement
amod = asm_encode_amod(ops_following, AM_MEMI, displacement)
amod = asm_encode_amod(data_type, AM_MEMI, displacement)
end if
else
if has_displacement = 1 then ' memory direct + displacement
amod = asm_encode_amod(ops_following, AM_MEMDD, displacement)
amod = asm_encode_amod(data_type, AM_MEMDD, displacement)
else ' memory direct, no displacement
amod = asm_encode_amod(ops_following, AM_MEMD, displacement)
amod = asm_encode_amod(data_type, AM_MEMD, displacement)
end if
end if
end if
......@@ -519,9 +519,9 @@ sub asm_assemble(instruction as string)
dim operand_count as integer = 0
dim opcode as ubyte = 0
dim operand as t_operand
dim ops_following as ubyte = 0
dim data_type as ubyte = 0
dim i as integer
dim inst as string
......@@ -591,7 +591,7 @@ function asm_disassemble(page as ushort, offset as ushort) as string
dim operand_count as ubyte
dim i as ushort
dim displacement as ushort
dim ops_following as ubyte
dim data_type as ubyte
dim actual_amod as ubyte
dim addr as ushort
dim lsb as ubyte
......
......@@ -23,12 +23,12 @@ type t_operand
data_type as ubyte ' 0 = byte, 1 = word
end type
declare function asm_encode_amod(ops_following as ubyte, amod as ubyte, disp as ubyte) as ubyte
declare function asm_encode_amod(data_type as ubyte, amod as ubyte, disp as ubyte) as ubyte
declare function asm_amod_datatype(amod as ubyte) as ubyte
declare function asm_amod_amod(amod as ubyte) as ubyte
declare function asm_amod_disp(amod as ubyte) as ubyte
declare function asm_decode_disp(disp as ubyte) as ushort
declare function asm_encode_address(ops_following as ubyte, addr_string as string) as t_operand
declare function asm_encode_address(data_type as ubyte, addr_string as string) as t_operand
declare function asm_encode_register(register_name as string) as ubyte
declare function asm_decode_register(reg as ubyte) as string
declare function asm_encode_opcode(instruction as string) as ubyte
......
......@@ -48,7 +48,7 @@ sub bus_start()
dim i as integer
for i = 1 to dev_count
message_print "bus_start(): starting device " & devices(i)
message_print "bus_start(): starting device " & devices(i) & " (" & rtrim(bus(devices(i)).dev_tag) & ")"
bus(devices(i)).dev_thread = threadcreate(bus(devices(i)).dev_cycle, @devices(i))
bus(devices(i)).dev_thread_started = 1
......@@ -58,7 +58,8 @@ sub bus_start()
sleep 500
bus_started = 1
message_print "bus_start(): system bus is ready"
end sub
sub bus_stop()
......
'
' console.bas
'
'
#include "console.bi"
#include "storage.bi"
......@@ -10,17 +10,17 @@
sub console_attach()
dim dev as dev_entry
dim console_device as dev_entry
dim console_mode as string = config_get("console", "mode")
select case console_mode
case "local"
with dev
with console_device
.dev_tag = "console"
.io_base = 0
.io_port_count = 4
.io_port_count = 5
.dev_init = @console_init_local
.dev_reset = @console_reset_local
.dev_cycle = @console_cycle_local
......@@ -32,7 +32,7 @@ sub console_attach()
case "serial"
with dev
with console_device
.dev_tag = "console"
.io_base = 0
.io_port_count = 4
......@@ -54,7 +54,7 @@ sub console_attach()
end select
bus_attach 0, dev
bus_attach 0, console_device
end sub
......@@ -91,11 +91,55 @@ sub console_reset_serial()
end sub
function console_input(port_number as ushort) as ushort
return 0
select case port_number
case (console_io_base + 0)
return cursor_enabled
case (console_io_base + 1)
return sleep_duration
case (console_io_base + 2)
return horizontal_offset
case (console_io_base + 3)
return vertical_offset
case else
return 0
end select
end function
sub console_output(port_number as ushort, value as ushort)
dim i as integer
select case port_number
case (console_io_base + 0)
if value = 0 then
cursor_enabled = 0
else
cursor_enabled = 1
end if
case (console_io_base + 1)
sleep_duration = value
case (console_io_base + 2)
horizontal_offset = value
case (console_io_base + 3)
vertical_offset = value
case (console_io_base + 4)
for i = CONSOLE_OFFSET to CONSOLE_LIMIT - 1
st_write_byte CONSOLE_PAGE, i, 0
next i
end select
end sub
sub console_cycle_local(byval userdata as any ptr)
......@@ -136,7 +180,7 @@ sub console_cycle_local(byval userdata as any ptr)
mutexunlock console_mutex
sleep 25
sleep sleep_duration, 1
if bus_get_stop_flag(0) = 1 then exit do
loop
......@@ -174,7 +218,7 @@ sub console_cycle_serial(byval userdata as any ptr)
c = st_read_byte(CONSOLE_PAGE, i)
output_str = chr(27) & "[" & trim(str(row)) & ";" & trim(str(col)) & "H" & chr(c)
output_str = chr(27) & "[" & trim(str(row + horizontal_offset)) & ";" & trim(str(col + vertical_offset)) & "H" & chr(c)
print #console_file_number, output_str;
......@@ -186,7 +230,7 @@ sub console_cycle_serial(byval userdata as any ptr)
end if
next i
sleep 25, 1
sleep sleep_duration, 1
if bus_get_stop_flag(0) = 1 then exit do
loop
......
......@@ -2,6 +2,26 @@
' console.bi
'
'
' I/O PORT USAGE
'
' OUT
'
' IOBASE + 0: 1 = Enable Cursor; 0 = Disable Cursor
' 1: Set refresh sleep value (ms)
' 2: Set horizontal offset
' 3: Set vertical offset
' 4: Write to this port to clear video buffer
'
' IN
'
' IOBASE + 0: Read cursor enable value
' 1: Read refresh sleep value (ms)
' 2: Read horizontal offset
' 3: Read vertical offset
' 4: Nonsense!
#define CONSOLE_PAGE &H0001
#define CONSOLE_OFFSET &H0000
#define CONSOLE_LIMIT &H07D0
......@@ -17,8 +37,15 @@ dim shared console_parity as string
dim shared console_data_bits as string
dim shared console_stop_bits as string
dim shared horizontal_offset as ushort = 0
dim shared vertical_offset as ushort = 0
dim shared sleep_duration as ushort = 50
dim shared cursor_enabled as ushort = 1
dim shared console_file_number as integer
dim shared console_io_base as ushort
declare sub console_attach()
declare sub console_init_local()
declare sub console_reset_local()
......
......@@ -10,13 +10,13 @@
'
'PC + 0 7 8 9 C D F 10
' +--------+-+----+---+--------+
' |OPCODE |O|MOD |DSP|OPERAND |
' |OPCODE |T|MOD |DSP|OPERAND |
' +--------+-+----+---+--------+
' |BYTE 1 | BYTE 2 |BYTE 3 |
' +--------+----------+--------+
'
' OPCODE (instruction opcode) 0-255
' O (data type) 0 = byte; 1 = word
' T (data type) 0 = byte; 1 = word
' MOD (addressing mode)
' 0 0000 = immediate
' 1 0001 = register direct
......
'
' disk.bas
'
#include "disk.bi"
#include "storage.bi"
#include "bus.bi"
#include "config.bi"
#include "message.bi"
'
' OUT
'
' IOBASE + 0: Set channel
' 1: Set sector memory buffer page
' 2: Set sector memory buffer offset
' 3: Set disk track for current channel
' 4: Set disk sector for current channel
' 5: Read current track/sector into sector memory buffer
' 6: Write current sector memory buffer to current track/sector
'
' IN
'
' IOBASE + 0: Get installed channel count
' 1: Get track count for current channel
' 2: Get sectors-per-track count for current channel
'
sub disk_attach()
dim disk_device as dev_entry
with disk_device
.dev_tag = "disk"
.io_base = 240
.io_port_count = 10
.dev_init = @disk_init
.dev_reset = @disk_reset
.dev_cycle = @disk_cycle
.dev_input = @disk_input
.dev_output = @disk_output
end with
bus_attach 5, disk_device
end sub
sub disk_init()
end sub
sub disk_reset()
end sub
function disk_input(port_number as ushort) as ushort
select case port_number
case (disk_io_base + 0)
case (disk_io_base + 1)
case (disk_io_base + 2)
case (disk_io_base + 3)
case (disk_io_base + 4)
case (disk_io_base + 5)
case (disk_io_base + 6)
end select
end function
sub disk_output(port_number as ushort, value as ushort)
select case port_number
case (disk_io_base + 0)
case (disk_io_base + 1)
case (disk_io_base + 2)
case (disk_io_base + 3)
case (disk_io_base + 4)
case (disk_io_base + 5)
case (disk_io_base + 6)
end select
end sub
sub disk_cycle(byval userdata as any ptr)
do
sleep 500
if bus_get_stop_flag(5) = 1 then exit do
loop
end sub
\ No newline at end of file
'
' disk.bi
'
type disk_header_t
magic as string * 3
track_count as ushort
sectors_per_track as ushort
end type
type disk_track_t
sectors(512) as disk_sector_t
end type
type disk_sector_t
sector(512) as ubyte
end type
\ No newline at end of file
......@@ -14,7 +14,9 @@
EQU ROM_DATA_PAGE 0
EQU ROM_STACK 10 ; ROM RESERVES PAGE 10 FOR STACK OPERATIONS
EQU SPINNER_POS 75 ; SPINNER POSITION
LABEL __rom_start
;;
;; JUMP TO ROM INITIALIZATION ROUTINE
......@@ -32,6 +34,21 @@ LABEL __rom_init
COPY WORD %DP,{ROM_DATA_PAGE}
COPY WORD %SP,{ROM_STACK}
;;
;; DISABLE HARDWARE CURSOR AND SET SLEEP RATE
;;
OUT WORD 0,1
OUT WORD 1,25
OUT WORD 2,10
OUT WORD 3,5
COPY BYTE %LA,92 ; \
COPY BYTE %LB,124 ; |
COPY BYTE %LC,47 ; /
COPY WORD %GD,0
COPY BYTE %LE,{SPINNER_POS}
;;
;; PRINT ROM VERSION
;;
......@@ -39,8 +56,53 @@ LABEL __rom_init
COPY WORD %SI,{ROM_VS}
SCALL WORD {__term_print_string}
LABEL __loop
BRANCH WORD {__rom_init}
CMP WORD %GD,2
BEQ WORD {__reset_counter}
ADD WORD %GD,1
BRANCH WORD {__no_reset}
LABEL __reset_counter
COPY WORD %GD,0
LABEL __no_reset
CMP WORD %GD,0
BEQ WORD {__backslash}
CMP WORD %GD,1
BEQ WORD {__pipe}
CMP WORD %GD,2
BEQ WORD {__fwdslash}
LABEL __backslash
COPY BYTE %HE,%LA
BRANCH WORD {__do_poke}
LABEL __pipe
COPY BYTE %HE,%LB
BRANCH WORD {__do_poke}
LABEL __fwdslash
COPY BYTE %HE,%LC
LABEL __do_poke
PUSH WORD %DS
COPY WORD %DS,{VID_PAGE}
COPY BYTE (%LE),%HE
POP WORD %DS
BRANCH WORD {__loop}
;; __term_print_string
;;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment