; Glue code for the emulated environment .equ RAMSTART 0x4000 .equ USER_CODE 0x4800 .equ STDIO_PORT 0x00 .equ STDIN_SEEK 0x01 .equ FS_DATA_PORT 0x02 .equ FS_SEEK_PORT 0x03 jp init ; 3 bytes ; *** JUMP TABLE *** jp strncmp jp addDE jp addHL jp upcase jp unsetZ jp intoDE jp intoHL jp findchar jp parseHexPair jp blkSel jp fsFindFN jp fsOpen jp fsGetC jp fsSeek jp fsTell #include "core.asm" #include "parse.asm" .equ BLOCKDEV_RAMSTART RAMSTART .equ BLOCKDEV_COUNT 3 #include "blockdev.asm" ; List of devices .dw emulGetC, 0, emulSeek, emulTell .dw 0, emulPutC, 0, 0 .dw fsdevGetC, fsdevPutC, fsdevSeek, fsdevTell .equ FS_RAMSTART BLOCKDEV_RAMEND .equ FS_HANDLE_COUNT 0 #include "fs.asm" init: di ; We put the stack at the end of the kernel memory ld hl, USER_CODE-1 ld sp, hl ld a, 2 ; select fsdev ld de, BLOCKDEV_GETC call blkSel call fsOn ld h, 0 ; input blkdev ld l, 1 ; output blkdev call USER_CODE ; signal the emulator we're done halt emulGetC: in a, (STDIO_PORT) or a ; cp 0 jr z, .eof cp a ; ensure z ret .eof: call unsetZ ret emulPutC: out (STDIO_PORT), a ret emulSeek: ; the STDIN_SEEK port works by poking it twice. First poke is for high ; byte, second poke is for low one. ld a, h out (STDIN_SEEK), a ld a, l out (STDIN_SEEK), a ret emulTell: ; same principle as STDIN_SEEK in a, (STDIN_SEEK) ld h, a in a, (STDIN_SEEK) ld l, a ret fsdevGetC: in a, (FS_DATA_PORT) cp a ; ensure Z ret fsdevPutC: out (FS_DATA_PORT), a ret fsdevSeek: push af ld a, h out (FS_SEEK_PORT), a ld a, l out (FS_SEEK_PORT), a pop af ret fsdevTell: push af in a, (FS_SEEK_PORT) ld h, a in a, (FS_SEEK_PORT) ld l, a pop af ret