explicitly pass data disk to main
This commit is contained in:
parent
9818f1de98
commit
7bf8adb893
4
400.mu
4
400.mu
|
@ -9,8 +9,8 @@ sig draw-cursor-on-real-screen g: grapheme
|
||||||
sig read-key kbd: (addr keyboard) -> _/eax: byte
|
sig read-key kbd: (addr keyboard) -> _/eax: byte
|
||||||
|
|
||||||
# disk
|
# disk
|
||||||
sig load-first-sector-from-primary-bus-secondary-drive out: (addr stream byte)
|
sig load-sector disk: (addr disk), lba: int, out: (addr stream byte)
|
||||||
sig store-first-sector-to-primary-bus-secondary-drive out: (addr stream byte)
|
sig store-sector disk: (addr disk), lba: int, out: (addr stream byte)
|
||||||
|
|
||||||
# mouse
|
# mouse
|
||||||
sig read-mouse-event -> _/eax: int, _/ecx: int
|
sig read-mouse-event -> _/eax: int, _/ecx: int
|
||||||
|
|
395
boot.subx
395
boot.subx
|
@ -814,7 +814,42 @@ Font:
|
||||||
# https://forum.osdev.org/viewtopic.php?f=1&p=167798
|
# https://forum.osdev.org/viewtopic.php?f=1&p=167798
|
||||||
# read-sector, according to https://www.scs.stanford.edu/11wi-cs140/pintos/specs/ata-3-std.pdf
|
# read-sector, according to https://www.scs.stanford.edu/11wi-cs140/pintos/specs/ata-3-std.pdf
|
||||||
|
|
||||||
load-first-sector-from-primary-bus-secondary-drive: # out: (addr stream byte)
|
== data
|
||||||
|
|
||||||
|
# We'll be gaining access just to the secondary drive on the primary bus for
|
||||||
|
# now. It will have the designated 'data' disk so we don't mess with the code
|
||||||
|
# disk.
|
||||||
|
#
|
||||||
|
# The type definition for this variable is in safe Mu (rather than unsafe
|
||||||
|
# SubX) code.
|
||||||
|
# All ports are 8-bit except data-port, which is 16-bit.
|
||||||
|
Primary-bus-secondary-drive:
|
||||||
|
# command-port: int (write)
|
||||||
|
0x1f7/imm32
|
||||||
|
# status-port: int (read)
|
||||||
|
0x1f7/imm32
|
||||||
|
# alternative-status-port: int (read)
|
||||||
|
0x3f6/imm32
|
||||||
|
# error-port: int (read)
|
||||||
|
0x1f1/imm32
|
||||||
|
# drive-and-head-port: int
|
||||||
|
0x1f6/imm32
|
||||||
|
# sector-count-port: int
|
||||||
|
0x1f2/imm32
|
||||||
|
# lba-low-port: int
|
||||||
|
0x1f3/imm32
|
||||||
|
# lba-mid-port: int
|
||||||
|
0x1f4/imm32
|
||||||
|
# lba-high-port: int
|
||||||
|
0x1f5/imm32
|
||||||
|
# data-port: int
|
||||||
|
0x1f0/imm32
|
||||||
|
# drive-code: byte # only drive-specific field
|
||||||
|
0xf0/imm32 # LBA mode also enabled
|
||||||
|
|
||||||
|
== code
|
||||||
|
|
||||||
|
load-sector: # disk: (addr disk), lba: int, out: (addr stream byte)
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
|
@ -823,35 +858,46 @@ load-first-sector-from-primary-bus-secondary-drive: # out: (addr stream byte)
|
||||||
51/push-ecx
|
51/push-ecx
|
||||||
52/push-edx
|
52/push-edx
|
||||||
# check for drive
|
# check for drive
|
||||||
(secondary-drive-exists?) # => eax
|
(drive-exists? *(ebp+8)) # => eax
|
||||||
3d/compare-eax-and 0/imm32/false
|
3d/compare-eax-and 0/imm32/false
|
||||||
0f 84/jump-if-= $load-first-sector-from-primary-bus-secondary-drive:end/disp32
|
0f 84/jump-if-= $load-sector:end/disp32
|
||||||
# kick off read
|
# kick off read
|
||||||
(ata-drive-select 0xf0) # primary bus, secondary drive; 4 LSBs contain 4 upper bits of LBA (here 0)
|
(ata-drive-select *(ebp+8) *(ebp+0xc))
|
||||||
(clear-ata-error)
|
(clear-ata-error *(ebp+8))
|
||||||
(ata-sector-count 1)
|
(ata-sector-count *(ebp+8) 1)
|
||||||
(ata-lba 0 0 0) # lower 24 bits of LBA, all 0
|
(ata-lba *(ebp+8) *(ebp+0xc))
|
||||||
(ata-command 0x20) # read sectors with retries
|
(ata-command *(ebp+8) 0x20) # read sectors with retries
|
||||||
# poll for results
|
# poll for results
|
||||||
(while-ata-busy)
|
(while-ata-busy *(ebp+8))
|
||||||
(until-ata-data-available)
|
(until-ata-data-available *(ebp+8))
|
||||||
|
# var data-port/edx = disk->data-port
|
||||||
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
|
8b/-> *(eax+0x24) 2/r32/edx
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "A: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
# emit results
|
# emit results
|
||||||
31/xor %eax 0/r32/eax
|
31/xor %eax 0/r32/eax
|
||||||
ba/copy-to-edx 0x1f0/imm32
|
|
||||||
b9/copy-to-ecx 0x200/imm32 # 512 bytes per sector
|
b9/copy-to-ecx 0x200/imm32 # 512 bytes per sector
|
||||||
{
|
{
|
||||||
81 7/subop/compare %ecx 0/imm32
|
81 7/subop/compare %ecx 0/imm32
|
||||||
74/jump-if-= break/disp8
|
74/jump-if-= break/disp8
|
||||||
66 ed/read-port-dx-into-ax
|
66 ed/read-port-dx-into-ax
|
||||||
# write 2 bytes to stream one at a time
|
# write 2 bytes to stream one at a time
|
||||||
(append-byte *(ebp+8) %eax)
|
(append-byte *(ebp+0x10) %eax)
|
||||||
49/decrement-ecx
|
49/decrement-ecx
|
||||||
c1/shift 5/subop/right-padding-zeroes %eax 8/imm8
|
c1/shift 5/subop/right-padding-zeroes %eax 8/imm8
|
||||||
(append-byte *(ebp+8) %eax)
|
(append-byte *(ebp+0x10) %eax)
|
||||||
49/decrement-ecx
|
49/decrement-ecx
|
||||||
eb/jump loop/disp8
|
eb/jump loop/disp8
|
||||||
}
|
}
|
||||||
$load-first-sector-from-primary-bus-secondary-drive:end:
|
$load-sector:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
5a/pop-to-edx
|
5a/pop-to-edx
|
||||||
59/pop-to-ecx
|
59/pop-to-ecx
|
||||||
|
@ -861,7 +907,7 @@ $load-first-sector-from-primary-bus-secondary-drive:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
store-first-sector-to-primary-bus-secondary-drive: # in: (addr stream byte)
|
store-sector: # disk: (addr disk), lba: int, in: (addr stream byte)
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
|
@ -871,40 +917,42 @@ store-first-sector-to-primary-bus-secondary-drive: # in: (addr stream byte)
|
||||||
52/push-edx
|
52/push-edx
|
||||||
53/push-ebx
|
53/push-ebx
|
||||||
# check for drive
|
# check for drive
|
||||||
(secondary-drive-exists?) # => eax
|
(drive-exists? *(ebp+8)) # => eax
|
||||||
3d/compare-eax-and 0/imm32/false
|
3d/compare-eax-and 0/imm32/false
|
||||||
0f 84/jump-if-= $store-first-sector-to-primary-bus-secondary-drive:end/disp32
|
0f 84/jump-if-= $store-sector:end/disp32
|
||||||
# kick off write
|
# kick off write
|
||||||
(ata-drive-select 0xf0) # primary bus, secondary drive; 4 LSBs contain 4 upper bits of LBA (here 0)
|
(ata-drive-select *(ebp+8) *(ebp+0xc))
|
||||||
(clear-ata-error)
|
(clear-ata-error *(ebp+8))
|
||||||
(ata-sector-count 1)
|
(ata-sector-count *(ebp+8) 1)
|
||||||
(ata-lba 0 0 0) # lower 24 bits of LBA, all 0
|
(ata-lba *(ebp+8) *(ebp+0xc))
|
||||||
(ata-command 0x30) # write sectors with retries
|
(ata-command *(ebp+8) 0x30) # write sectors with retries
|
||||||
# wait
|
# wait
|
||||||
(while-ata-busy)
|
(while-ata-busy *(ebp+8))
|
||||||
(until-ata-ready-for-data)
|
(until-ata-ready-for-data *(ebp+8))
|
||||||
|
# var data-port/edx = disk->data-port
|
||||||
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
|
8b/-> *(eax+0x24) 2/r32/edx
|
||||||
# send data
|
# send data
|
||||||
ba/copy-to-edx 0x1f0/imm32
|
|
||||||
b9/copy-to-ecx 0x200/imm32 # 512 bytes per sector
|
b9/copy-to-ecx 0x200/imm32 # 512 bytes per sector
|
||||||
# var first-byte/ebx: byte
|
# . var first-byte/ebx: byte
|
||||||
# when it's more than 0xff, we're at an even-numbered byte
|
# . when it's more than 0xff, we're at an even-numbered byte
|
||||||
bb/copy-to-ebx 0xffff/imm32
|
bb/copy-to-ebx 0xffff/imm32
|
||||||
$store-first-sector-to-primary-bus-secondary-drive:loop:
|
$store-sector:loop:
|
||||||
{
|
{
|
||||||
81 7/subop/compare %ecx 0/imm32
|
81 7/subop/compare %ecx 0/imm32
|
||||||
74/jump-if-= break/disp8
|
74/jump-if-= break/disp8
|
||||||
# this loop is slow, but the ATA spec also requires a small delay
|
# this loop is slow, but the ATA spec also requires a small delay
|
||||||
(stream-empty? *(ebp+8)) # => eax
|
(stream-empty? *(ebp+0x10)) # => eax
|
||||||
3d/compare-eax-and 0/imm32/false
|
3d/compare-eax-and 0/imm32/false
|
||||||
75/jump-if-!= break/disp8
|
75/jump-if-!= break/disp8
|
||||||
# read byte from stream
|
# read byte from stream
|
||||||
(read-byte *(ebp+8)) # => eax
|
(read-byte *(ebp+0x10)) # => eax
|
||||||
# if we're at an odd-numbered byte, save it to first-byte
|
# if we're at an odd-numbered byte, save it to first-byte
|
||||||
81 7/subop/compare %ebx 0xff/imm32
|
81 7/subop/compare %ebx 0xff/imm32
|
||||||
{
|
{
|
||||||
7e/jump-if-<= break/disp8
|
7e/jump-if-<= break/disp8
|
||||||
89/<- %ebx 0/r32/eax
|
89/<- %ebx 0/r32/eax
|
||||||
eb/jump $store-first-sector-to-primary-bus-secondary-drive:loop/disp8
|
eb/jump $store-sector:loop/disp8
|
||||||
}
|
}
|
||||||
# otherwise OR it with first-byte and write it out
|
# otherwise OR it with first-byte and write it out
|
||||||
c1/shift 4/subop/left %eax 8/imm8
|
c1/shift 4/subop/left %eax 8/imm8
|
||||||
|
@ -935,7 +983,7 @@ $store-first-sector-to-primary-bus-secondary-drive:loop:
|
||||||
49/decrement-ecx
|
49/decrement-ecx
|
||||||
eb/jump loop/disp8
|
eb/jump loop/disp8
|
||||||
}
|
}
|
||||||
$store-first-sector-to-primary-bus-secondary-drive:end:
|
$store-sector:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
5b/pop-to-ebx
|
5b/pop-to-ebx
|
||||||
5a/pop-to-edx
|
5a/pop-to-edx
|
||||||
|
@ -948,7 +996,7 @@ $store-first-sector-to-primary-bus-secondary-drive:end:
|
||||||
|
|
||||||
# disk helpers {{{
|
# disk helpers {{{
|
||||||
|
|
||||||
secondary-drive-exists?: # -> _/eax: boolean
|
drive-exists?: # disk: (addr disk) -> _/eax: boolean
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
|
@ -958,36 +1006,68 @@ secondary-drive-exists?: # -> _/eax: boolean
|
||||||
{
|
{
|
||||||
31/xor %eax 0/r32/eax
|
31/xor %eax 0/r32/eax
|
||||||
ba/copy-to-edx 0x1f7/imm32
|
ba/copy-to-edx 0x1f7/imm32
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "B: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
ec/read-port-dx-into-al
|
ec/read-port-dx-into-al
|
||||||
3d/compare-eax-and 0xff/imm32
|
3d/compare-eax-and 0xff/imm32
|
||||||
# if eax is 0xff, primary bus has no drives
|
# if eax is 0xff, primary bus has no drives
|
||||||
b8/copy-to-eax 0/imm32/false
|
b8/copy-to-eax 0/imm32/false
|
||||||
74/jump-if-= $secondary-drive-exists?:end/disp8
|
74/jump-if-= $drive-exists?:end/disp8
|
||||||
}
|
}
|
||||||
# identify
|
# identify
|
||||||
(ata-drive-select 0xf0) # primary bus, secondary drive
|
(ata-drive-select *(ebp+8) 0)
|
||||||
(ata-sector-count 0)
|
(ata-sector-count *(ebp+8) 0)
|
||||||
(ata-lba 0 0 0)
|
(ata-lba *(ebp+8) 0)
|
||||||
(ata-command 0xec) # identify
|
(ata-command *(ebp+8) 0xec) # identify
|
||||||
# read status register
|
# var status-port/edx = disk->status-port
|
||||||
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
|
8b/-> *(eax+4) 2/r32/edx # 4 = status-port offset
|
||||||
|
# read status port
|
||||||
# TODO: might need to spin here for 400ns: https://wiki.osdev.org/index.php?title=ATA_PIO_Mode&oldid=25664#400ns_delays
|
# TODO: might need to spin here for 400ns: https://wiki.osdev.org/index.php?title=ATA_PIO_Mode&oldid=25664#400ns_delays
|
||||||
31/xor %eax 0/r32/eax
|
31/xor %eax 0/r32/eax
|
||||||
ba/copy-to-edx 0x1f7/imm32
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "C: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
ec/read-port-dx-into-al
|
ec/read-port-dx-into-al
|
||||||
# if eax is 0, secondary drive does not exist
|
# if eax is 0, drive does not exist
|
||||||
3d/compare-eax-and 0/imm32
|
3d/compare-eax-and 0/imm32
|
||||||
{
|
{
|
||||||
74/jump-if-= break/disp8
|
74/jump-if-= break/disp8
|
||||||
b8/copy-to-eax 1/imm32/true
|
b8/copy-to-eax 1/imm32/true
|
||||||
eb/jump $secondary-drive-exists?:complete-identify/disp8
|
eb/jump $drive-exists?:complete-identify/disp8
|
||||||
}
|
}
|
||||||
# TODO: might need to perform remaining steps at https://wiki.osdev.org/index.php?title=ATA_PIO_Mode&oldid=25664#IDENTIFY_command
|
# TODO: might need to perform remaining steps at https://wiki.osdev.org/index.php?title=ATA_PIO_Mode&oldid=25664#IDENTIFY_command
|
||||||
b8/copy-to-eax 0/imm32/false
|
b8/copy-to-eax 0/imm32/false
|
||||||
$secondary-drive-exists?:complete-identify:
|
$drive-exists?:complete-identify:
|
||||||
50/push-eax
|
50/push-eax
|
||||||
|
# var data-port/edx = disk->data-port
|
||||||
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
|
8b/-> *(eax+0x24) 2/r32/edx # 0x24 = data-port offset
|
||||||
# clear FIFO from the drive
|
# clear FIFO from the drive
|
||||||
ba/copy-to-edx 0x1f0/imm32
|
|
||||||
b9/copy-to-ecx 0x200/imm32
|
b9/copy-to-ecx 0x200/imm32
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "D: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
{
|
{
|
||||||
81 7/subop/compare %ecx 0/imm32
|
81 7/subop/compare %ecx 0/imm32
|
||||||
74/jump-if-= break/disp8
|
74/jump-if-= break/disp8
|
||||||
|
@ -1000,7 +1080,7 @@ $secondary-drive-exists?:complete-identify:
|
||||||
eb/jump loop/disp8
|
eb/jump loop/disp8
|
||||||
}
|
}
|
||||||
58/pop-to-eax
|
58/pop-to-eax
|
||||||
$secondary-drive-exists?:end:
|
$drive-exists?:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
5a/pop-to-edx
|
5a/pop-to-edx
|
||||||
# . epilogue
|
# . epilogue
|
||||||
|
@ -1008,19 +1088,45 @@ $secondary-drive-exists?:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
ata-drive-select: # n: byte
|
ata-drive-select: # disk: (addr disk), lba: int
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
50/push-eax
|
||||||
52/push-edx
|
52/push-edx
|
||||||
#
|
56/push-esi
|
||||||
8b/-> *(ebp+8) 0/r32/eax
|
# esi = disk
|
||||||
ba/copy-to-edx 0x1f6/imm32
|
8b/-> *(ebp+8) 6/r32/esi
|
||||||
|
# var drive-head/edx: byte = lba >> 24
|
||||||
|
8b/-> *(ebp+0xc) 2/r32/edx
|
||||||
|
c1/shift 5/subop/right-padding-zeroes %edx 0x18/imm8
|
||||||
|
# var drive-code/eax: byte = disk->drive-code | drive-head
|
||||||
|
8b/-> *(esi+0x28) 0/r32/eax # 0x28 = drive-code offset
|
||||||
|
09/or= %eax 2/r32/edx
|
||||||
|
# var drive-and-head-port/edx: int
|
||||||
|
8b/-> *(esi+0x10) 2/r32/edx # 0x10 = drive-and-head-port offset
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "E: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 7 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %eax 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
ee/write-al-into-port-dx
|
ee/write-al-into-port-dx
|
||||||
$ata-drive-select:end:
|
$ata-drive-select:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
|
5e/pop-to-esi
|
||||||
5a/pop-to-edx
|
5a/pop-to-edx
|
||||||
58/pop-to-eax
|
58/pop-to-eax
|
||||||
# . epilogue
|
# . epilogue
|
||||||
|
@ -1028,16 +1134,35 @@ $ata-drive-select:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
clear-ata-error:
|
clear-ata-error: # disk: (addr disk)
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
50/push-eax
|
||||||
52/push-edx
|
52/push-edx
|
||||||
|
# var error-port/edx = disk->error-port
|
||||||
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
|
8b/-> *(eax+0xc) 2/r32/edx # 0xc = error-port offset
|
||||||
#
|
#
|
||||||
b8/copy-to-eax 0/imm32
|
b8/copy-to-eax 0/imm32
|
||||||
ba/copy-to-edx 0x1f1/imm32
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "F: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 7 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %eax 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
ee/write-al-into-port-dx
|
ee/write-al-into-port-dx
|
||||||
$ata-error:end:
|
$ata-error:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
|
@ -1048,16 +1173,35 @@ $ata-error:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
ata-sector-count: # n: byte
|
ata-sector-count: # disk: (addr disk), n: byte
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
50/push-eax
|
||||||
52/push-edx
|
52/push-edx
|
||||||
#
|
# var sector-count-port/edx = disk->sector-count-port
|
||||||
8b/-> *(ebp+8) 0/r32/eax
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
ba/copy-to-edx 0x1f2/imm32
|
8b/-> *(eax+0x14) 2/r32/edx # 0x14 = sector-count-port offset
|
||||||
|
#
|
||||||
|
8b/-> *(ebp+0xc) 0/r32/eax
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "G: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 7 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %eax 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
ee/write-al-into-port-dx
|
ee/write-al-into-port-dx
|
||||||
$ata-sector-count:end:
|
$ata-sector-count:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
|
@ -1068,24 +1212,68 @@ $ata-sector-count:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
ata-lba: # lo: byte, mid: byte, hi: byte
|
ata-lba: # disk: (addr disk), lba: int
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
50/push-eax
|
||||||
52/push-edx
|
52/push-edx
|
||||||
# lo
|
# var port/edx = disk->port
|
||||||
8b/-> *(ebp+8) 0/r32/eax
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
ba/copy-to-edx 0x1f3/imm32
|
8b/-> *(eax+0x18) 2/r32/edx # 0x18 = lba-low-port offset
|
||||||
|
# eax = lba
|
||||||
|
8b/-> *(ebp+0xc) 0/r32/eax
|
||||||
|
# lo
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "H: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 7 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %eax 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
ee/write-al-into-port-dx
|
ee/write-al-into-port-dx
|
||||||
# mid
|
# mid
|
||||||
8b/-> *(ebp+0xc) 0/r32/eax
|
42/increment-dx # lba-mid-port
|
||||||
ba/copy-to-edx 0x1f4/imm32
|
c1/shift 5/subop/right-padding-zeroes %eax 8/imm8
|
||||||
|
{
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "I: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %eax 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
}
|
||||||
ee/write-al-into-port-dx
|
ee/write-al-into-port-dx
|
||||||
# hi
|
# hi
|
||||||
8b/-> *(ebp+0x10) 0/r32/eax
|
42/increment-dx # lba-high-port
|
||||||
ba/copy-to-edx 0x1f5/imm32
|
c1/shift 5/subop/right-padding-zeroes %eax 8/imm8
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "J: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 7 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %eax 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
ee/write-al-into-port-dx
|
ee/write-al-into-port-dx
|
||||||
$ata-lba:end:
|
$ata-lba:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
|
@ -1096,46 +1284,35 @@ $ata-lba:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
# sector: [1, 63]
|
ata-command: # disk: (addr disk), cmd: byte
|
||||||
# cylinder: [0, 1023]
|
|
||||||
ata-cyl-sector: # sector: byte, cyl-lo: byte, cyl-hi: byte
|
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
50/push-eax
|
||||||
52/push-edx
|
52/push-edx
|
||||||
# sector
|
# var command-port/edx = disk->command-port
|
||||||
8b/-> *(ebp+8) 0/r32/eax
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
ba/copy-to-edx 0x1f3/imm32
|
8b/-> *(eax+0) 2/r32/edx # 0 = command-port offset
|
||||||
ee/write-al-into-port-dx
|
|
||||||
# cyl-lo
|
|
||||||
8b/-> *(ebp+0xc) 0/r32/eax
|
|
||||||
ba/copy-to-edx 0x1f4/imm32
|
|
||||||
ee/write-al-into-port-dx
|
|
||||||
# cyl-hi
|
|
||||||
8b/-> *(ebp+0x10) 0/r32/eax
|
|
||||||
ba/copy-to-edx 0x1f5/imm32
|
|
||||||
ee/write-al-into-port-dx
|
|
||||||
$ata-lba:end:
|
|
||||||
# . restore registers
|
|
||||||
5a/pop-to-edx
|
|
||||||
58/pop-to-eax
|
|
||||||
# . epilogue
|
|
||||||
89/<- %esp 5/r32/ebp
|
|
||||||
5d/pop-to-ebp
|
|
||||||
c3/return
|
|
||||||
|
|
||||||
ata-command: # cmd: byte
|
|
||||||
# . prologue
|
|
||||||
55/push-ebp
|
|
||||||
89/<- %ebp 4/r32/esp
|
|
||||||
# . save registers
|
|
||||||
50/push-eax
|
|
||||||
52/push-edx
|
|
||||||
#
|
#
|
||||||
8b/-> *(ebp+8) 0/r32/eax
|
8b/-> *(ebp+0xc) 0/r32/eax
|
||||||
ba/copy-to-edx 0x1f7/imm32
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "K: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 7 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %eax 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
ee/write-al-into-port-dx
|
ee/write-al-into-port-dx
|
||||||
$ata-command:end:
|
$ata-command:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
|
@ -1146,12 +1323,22 @@ $ata-command:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
while-ata-busy:
|
while-ata-busy: # disk: (addr disk)
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
50/push-eax
|
||||||
52/push-edx
|
52/push-edx
|
||||||
#
|
# var status-port/edx = disk->status-port
|
||||||
ba/copy-to-edx 0x1f7/imm32
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
|
8b/-> *(eax+4) 2/r32/edx # 4 = status-port offset
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "L: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
{
|
{
|
||||||
ec/read-port-dx-into-al
|
ec/read-port-dx-into-al
|
||||||
a8/test-bits-in-al 0x80/imm8/bsy # set zf if bit 7 (most significant) is not set
|
a8/test-bits-in-al 0x80/imm8/bsy # set zf if bit 7 (most significant) is not set
|
||||||
|
@ -1164,12 +1351,22 @@ $while-ata-busy:end:
|
||||||
# . epilogue
|
# . epilogue
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
until-ata-data-available:
|
until-ata-data-available: # disk: (addr disk)
|
||||||
# . save registers
|
# . save registers
|
||||||
50/push-eax
|
50/push-eax
|
||||||
52/push-edx
|
52/push-edx
|
||||||
#
|
# var status-port/edx = disk->status-port
|
||||||
ba/copy-to-edx 0x1f7/imm32
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
|
8b/-> *(eax+4) 2/r32/edx # 4 = status-port offset
|
||||||
|
{
|
||||||
|
50/push-eax
|
||||||
|
51/push-ecx
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "M: " 7 0)
|
||||||
|
(draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 7 0)
|
||||||
|
(move-cursor-to-left-margin-of-next-line 0)
|
||||||
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
|
}
|
||||||
{
|
{
|
||||||
ec/read-port-dx-into-al
|
ec/read-port-dx-into-al
|
||||||
a8/test-bits-in-al 8/imm8/drq # set zf if bit 3 is not set
|
a8/test-bits-in-al 8/imm8/drq # set zf if bit 3 is not set
|
||||||
|
|
2
ex10.mu
2
ex10.mu
|
@ -11,7 +11,7 @@
|
||||||
# Values between -256 and +255 as you move the mouse over the window.
|
# Values between -256 and +255 as you move the mouse over the window.
|
||||||
# You might need to click on the window once.
|
# You might need to click on the window once.
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
# repeatedly print out mouse driver results if non-zero
|
# repeatedly print out mouse driver results if non-zero
|
||||||
$main:event-loop: {
|
$main:event-loop: {
|
||||||
var dx/eax: int <- copy 0
|
var dx/eax: int <- copy 0
|
||||||
|
|
2
ex2.mu
2
ex2.mu
|
@ -7,7 +7,7 @@
|
||||||
# Or:
|
# Or:
|
||||||
# bochs -f bochsrc # bochsrc loads disk.img
|
# bochs -f bochsrc # bochsrc loads disk.img
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
var y/eax: int <- copy 0
|
var y/eax: int <- copy 0
|
||||||
{
|
{
|
||||||
compare y, 0x300/screen-height=768
|
compare y, 0x300/screen-height=768
|
||||||
|
|
2
ex3.mu
2
ex3.mu
|
@ -11,7 +11,7 @@
|
||||||
# Expected output: a new green pixel starting from the top left corner of the
|
# Expected output: a new green pixel starting from the top left corner of the
|
||||||
# screen every time you press a key (letter or digit)
|
# screen every time you press a key (letter or digit)
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
var x/ecx: int <- copy 0
|
var x/ecx: int <- copy 0
|
||||||
var y/edx: int <- copy 0
|
var y/edx: int <- copy 0
|
||||||
{
|
{
|
||||||
|
|
2
ex4.mu
2
ex4.mu
|
@ -9,6 +9,6 @@
|
||||||
#
|
#
|
||||||
# Expected output: letter 'A' in green near the top-left corner of screen
|
# Expected output: letter 'A' in green near the top-left corner of screen
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
draw-code-point screen, 0x41/A, 2/row, 1/col, 0xa/fg, 0/bg
|
draw-code-point screen, 0x41/A, 2/row, 1/col, 0xa/fg, 0/bg
|
||||||
}
|
}
|
||||||
|
|
2
ex5.mu
2
ex5.mu
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# Expected output: text in green near the top-left corner of screen
|
# Expected output: text in green near the top-left corner of screen
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
var dummy/eax: int <- draw-text-rightward screen, "hello from baremetal Mu!", 0x10/x, 0x400/xmax, 0x10/y, 0xa/fg, 0/bg
|
var dummy/eax: int <- draw-text-rightward screen, "hello from baremetal Mu!", 0x10/x, 0x400/xmax, 0x10/y, 0xa/fg, 0/bg
|
||||||
dummy <- draw-text-rightward screen, "you shouldn't see this", 0x10/x, 0xa0/xmax, 0x30/y, 3/fg, 0/bg # xmax is too narrow
|
dummy <- draw-text-rightward screen, "you shouldn't see this", 0x10/x, 0xa0/xmax, 0x30/y, 3/fg, 0/bg # xmax is too narrow
|
||||||
}
|
}
|
||||||
|
|
2
ex6.mu
2
ex6.mu
|
@ -9,7 +9,7 @@
|
||||||
#
|
#
|
||||||
# Expected output: a box and text that doesn't overflow it
|
# Expected output: a box and text that doesn't overflow it
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
# drawing text within a bounding box
|
# drawing text within a bounding box
|
||||||
draw-box-on-real-screen 0xf, 0x1f, 0x79, 0x51, 0x4
|
draw-box-on-real-screen 0xf, 0x1f, 0x79, 0x51, 0x4
|
||||||
var x/eax: int <- copy 0x20
|
var x/eax: int <- copy 0x20
|
||||||
|
|
2
ex7.mu
2
ex7.mu
|
@ -10,7 +10,7 @@
|
||||||
# Expected output: an interactive game a bit like "snakes". Try pressing h, j,
|
# Expected output: an interactive game a bit like "snakes". Try pressing h, j,
|
||||||
# k, l.
|
# k, l.
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
var space/eax: grapheme <- copy 0x20
|
var space/eax: grapheme <- copy 0x20
|
||||||
set-cursor-position screen, 0, 0
|
set-cursor-position screen, 0, 0
|
||||||
{
|
{
|
||||||
|
|
2
ex8.mu
2
ex8.mu
|
@ -6,7 +6,7 @@
|
||||||
# bochs -f bochsrc # bochsrc loads disk.img
|
# bochs -f bochsrc # bochsrc loads disk.img
|
||||||
# Set a breakpoint at 0x7c00 and start stepping.
|
# Set a breakpoint at 0x7c00 and start stepping.
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
var n/eax: int <- copy 0
|
var n/eax: int <- copy 0
|
||||||
var result/xmm0: float <- convert n
|
var result/xmm0: float <- convert n
|
||||||
}
|
}
|
||||||
|
|
6
ex9.mu
6
ex9.mu
|
@ -15,17 +15,17 @@
|
||||||
# 6. Notice that the data disk now contains the word count of the original text.
|
# 6. Notice that the data disk now contains the word count of the original text.
|
||||||
# xxd data.img |head
|
# xxd data.img |head
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
var text-storage: (stream byte 0x200)
|
var text-storage: (stream byte 0x200)
|
||||||
var text/esi: (addr stream byte) <- address text-storage
|
var text/esi: (addr stream byte) <- address text-storage
|
||||||
load-first-sector-from-primary-bus-secondary-drive text
|
load-sector data-disk, 0/lba, text
|
||||||
|
|
||||||
var word-count/eax: int <- word-count text
|
var word-count/eax: int <- word-count text
|
||||||
|
|
||||||
var result-storage: (stream byte 0x10)
|
var result-storage: (stream byte 0x10)
|
||||||
var result/edi: (addr stream byte) <- address result-storage
|
var result/edi: (addr stream byte) <- address result-storage
|
||||||
write-int32-decimal result, word-count
|
write-int32-decimal result, word-count
|
||||||
store-first-sector-to-primary-bus-secondary-drive result
|
store-sector data-disk, 0/lba, result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn word-count in: (addr stream byte) -> _/eax: int {
|
fn word-count in: (addr stream byte) -> _/eax: int {
|
||||||
|
|
2
life.mu
2
life.mu
|
@ -211,7 +211,7 @@ fn render grid: (addr array boolean) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
#? # allocate on the stack
|
#? # allocate on the stack
|
||||||
#? var grid1-storage: (array boolean 0xc000) # width * height
|
#? var grid1-storage: (array boolean 0xc000) # width * height
|
||||||
#? var grid1/esi: (addr array boolean) <- address grid1-storage
|
#? var grid1/esi: (addr array boolean) <- address grid1-storage
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# See translate for how this file is used.
|
# See translate for how this file is used.
|
||||||
#
|
#
|
||||||
# Mu programs start at a function called 'main' with this signature:
|
# Mu programs start at a function called 'main' with this signature:
|
||||||
# fn main screen: (addr screen), keyboard: (addr keyboard)
|
# fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk)
|
||||||
#
|
#
|
||||||
# All tests must pass first (the "power-on unit test").
|
# All tests must pass first (the "power-on unit test").
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ Entry:
|
||||||
(clear-real-screen)
|
(clear-real-screen)
|
||||||
c7 0/subop/copy *Real-screen-cursor-x 0/imm32
|
c7 0/subop/copy *Real-screen-cursor-x 0/imm32
|
||||||
c7 0/subop/copy *Real-screen-cursor-y 0/imm32
|
c7 0/subop/copy *Real-screen-cursor-y 0/imm32
|
||||||
(main 0 0)
|
(main 0 0 Primary-bus-secondary-drive)
|
||||||
}
|
}
|
||||||
|
|
||||||
# hang indefinitely
|
# hang indefinitely
|
||||||
|
|
5
mu.md
5
mu.md
|
@ -117,15 +117,16 @@ It takes an array of strings and returns a status code to Linux in register
|
||||||
Without an OS, the signature looks like this:
|
Without an OS, the signature looks like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard)
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk)
|
||||||
```
|
```
|
||||||
|
|
||||||
A screen and keyboard are explicitly passed in. The goal is for all hardware
|
A screen and keyboard are explicitly passed in. The goal is for all hardware
|
||||||
dependencies to always be explicit. However there are currently gaps:
|
dependencies to always be explicit. However there are currently gaps:
|
||||||
* The mouse is accessed implicitly
|
* The mouse is accessed implicitly
|
||||||
* The disk is accessed implicitly
|
|
||||||
* The screen argument only supports text-mode graphics. Pixel graphics rely
|
* The screen argument only supports text-mode graphics. Pixel graphics rely
|
||||||
on implicit access to the screen.
|
on implicit access to the screen.
|
||||||
|
* The Mu computer has two disks, and the disk containing Mu code is not
|
||||||
|
accessible.
|
||||||
|
|
||||||
## Blocks
|
## Blocks
|
||||||
|
|
||||||
|
|
2
rpn.mu
2
rpn.mu
|
@ -15,7 +15,7 @@
|
||||||
#
|
#
|
||||||
# Error handling is non-existent. This is just a prototype.
|
# Error handling is non-existent. This is just a prototype.
|
||||||
|
|
||||||
fn main screen: (addr screen), keyboard: (addr keyboard) {
|
fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
|
||||||
var in-storage: (stream byte 0x80)
|
var in-storage: (stream byte 0x80)
|
||||||
var in/esi: (addr stream byte) <- address in-storage
|
var in/esi: (addr stream byte) <- address in-storage
|
||||||
var y/ecx: int <- copy 0
|
var y/ecx: int <- copy 0
|
||||||
|
|
Loading…
Reference in New Issue