CosmOS had 1,161 bytes of Program Memory left before the address applications load at, and Tab completion is not going to fit in that with anything to spare. So the wall moves up one page: the system keeps below 0x4FFF and 0x2FFF, and an application is based at 0x5000 and 0x3000. A PAGE IS A CHEAP THING TO GIVE IT AND AN EXPENSIVE THING TO RUN OUT OF. An application still has 44K of Program Memory before the vector table and the largest one here uses 7.5K, so what was taken from applications is space nothing has ever asked for - while what the system gained is the difference between building the next thing and counting bytes while building it. Not doubling, which was the version that would have cost application space worth minding. One page, and the same again when it is needed. Nothing in the machine knows where the wall is, so this is 34 #Base lines, one threshold in the fault handler, and the table in the CosmOS README that Tests/docs.sh reads its limits out of. The native assembler's scratch map had to move with it, and docs.sh said so before anything ran: its data reached 0x40D6 and its buffers began at 0x4000, so they were sitting on its variables. That file already carries a paragraph about the floor coming up and the map staying where it was. It has happened twice now, and been caught by a check the first time wrote. Twenty three recordings are the same runs a page higher. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
179 lines
3.2 KiB
NASM
179 lines
3.2 KiB
NASM
; What the console just handed over, in hexadecimal and by name.
|
|
;
|
|
; The keys that are not characters - the arrows, Home, End and forward Delete - arrive as
|
|
; the console's own values above ASCII rather than as the escape sequences a terminal sends
|
|
; or as nothing at all, which is what a window used to make of them. This is what shows
|
|
; that, and it shows both halves of the rule in one run:
|
|
;
|
|
; A LINE FIRST, read the way everything reads one. Line mode delivers characters, so the
|
|
; keys are dropped before they reach the buffer and what comes back is what a person could
|
|
; have typed. Pressing Up while something else is collecting a line does nothing, which is
|
|
; an improvement on putting an escape and a bracket in the middle of it.
|
|
;
|
|
; THEN THE KEYS, in key mode, where a program has asked for every keystroke as it happens
|
|
; and these are keystrokes like any other.
|
|
;
|
|
; Written by Anachronaut
|
|
|
|
#Include services.asm
|
|
|
|
#Program
|
|
|
|
#Base 0x5000
|
|
|
|
start:
|
|
SETD.0 LineText
|
|
CALL printString
|
|
CALL newLine
|
|
|
|
SETD.0 Buffer
|
|
INIB 0d63
|
|
CALL readLine
|
|
|
|
SETD.0 Buffer
|
|
CALL showBytes
|
|
|
|
SETD.0 KeyText
|
|
CALL printString
|
|
CALL newLine
|
|
|
|
INIA 0x01
|
|
OUTA 0x02 ; Key mode. Nothing echoes, so everything below says what it saw.
|
|
keyLoop:
|
|
INA 0x00
|
|
INIB 0xFF
|
|
XOR
|
|
BRQ keyDone ; Nothing more is coming.
|
|
INIB 0x71 ; q, which is how this is stopped.
|
|
XOR
|
|
BRQ keyDone
|
|
CALL showKey
|
|
BRI keyLoop
|
|
|
|
keyDone:
|
|
RSTA
|
|
OUTA 0x02 ; Line mode, the way it was found.
|
|
SETD.0 DoneText
|
|
CALL printString
|
|
CALL newLine
|
|
RSTA
|
|
SWI osExit
|
|
|
|
; DP0 names a string of bytes ending in a zero. Prints each as two hexadecimal digits, so
|
|
; that what is in the buffer can be read rather than guessed at.
|
|
showBytes:
|
|
LDA.0
|
|
BRA showBytesDone
|
|
CALL printByteHex
|
|
INIA 0x20
|
|
OUTA 0x00
|
|
INCD.0
|
|
BRI showBytes
|
|
showBytesDone:
|
|
CALL newLine
|
|
RET
|
|
|
|
; A holds a key. Prints its value and then what it is.
|
|
;
|
|
; A survives a CALL, so the byte is still here after printing it - but only until something
|
|
; else is put in A, which the space below does. So it is kept where the naming can find it.
|
|
showKey:
|
|
SETD.1 KeyByte
|
|
STA.1
|
|
CALL printByteHex
|
|
INIA 0x20
|
|
OUTA 0x00
|
|
SETD.1 KeyByte
|
|
LDA.1
|
|
|
|
; XOR leaves the answer in Q and A alone, so one load stands for the whole ladder.
|
|
INIB 0x80
|
|
XOR
|
|
BRQ keyUp
|
|
INIB 0x81
|
|
XOR
|
|
BRQ keyDown
|
|
INIB 0x82
|
|
XOR
|
|
BRQ keyLeft
|
|
INIB 0x83
|
|
XOR
|
|
BRQ keyRight
|
|
INIB 0x84
|
|
XOR
|
|
BRQ keyHome
|
|
INIB 0x85
|
|
XOR
|
|
BRQ keyEnd
|
|
INIB 0x86
|
|
XOR
|
|
BRQ keyDelete
|
|
|
|
; An ordinary character, which is its own best name.
|
|
OUTA 0x00
|
|
CALL newLine
|
|
RET
|
|
|
|
keyUp:
|
|
SETD.0 UpText
|
|
BRI keySay
|
|
keyDown:
|
|
SETD.0 DownText
|
|
BRI keySay
|
|
keyLeft:
|
|
SETD.0 LeftText
|
|
BRI keySay
|
|
keyRight:
|
|
SETD.0 RightText
|
|
BRI keySay
|
|
keyHome:
|
|
SETD.0 HomeText
|
|
BRI keySay
|
|
keyEnd:
|
|
SETD.0 EndText
|
|
BRI keySay
|
|
keyDelete:
|
|
SETD.0 DeleteText
|
|
keySay:
|
|
CALL printString
|
|
CALL newLine
|
|
RET
|
|
|
|
#Data
|
|
|
|
#Base 0x3000
|
|
|
|
LineText:
|
|
"a line, then keys. q stops."
|
|
KeyText:
|
|
"keys:"
|
|
DoneText:
|
|
"done"
|
|
|
|
UpText:
|
|
"up"
|
|
DownText:
|
|
"down"
|
|
LeftText:
|
|
"left"
|
|
RightText:
|
|
"right"
|
|
HomeText:
|
|
"home"
|
|
EndText:
|
|
"end"
|
|
DeleteText:
|
|
"delete"
|
|
|
|
KeyByte:
|
|
0x00
|
|
|
|
Buffer:
|
|
#Reserve 0d64
|
|
|
|
#Vectors
|
|
|
|
Boot start
|
|
|
|
#Include console.asm
|